© Иван Рощин, Москва
| ZXNet | : 500:95/462.53 |
| : bestview@mtu-net.ru | |
| WWW | : http://www.ivr.da.ru |
(«Радиолюбитель. Ваш
компьютер» 6/2001, «Радиомир. Ваш компьютер» 7,8/2001
(под псевдонимом BV_Creator)).
Дата последнего редактирования: 14.02.2003.
Экскурс в историю
К дням сегодняшним
Проблема получает неожиданное решение
От теории к практике
Процедура построения частотной таблицы
Литература
Музыка это бессознательное упражнение души
в арифметике.
Г.Лейбниц
Давно было замечено, что частоты, находящиеся между собой в простых числовых соотношениях, наиболее приятны для слуха. Основываясь на этом, древние музыканты настраивали свои инструменты так, чтобы соотношения звуков в октаве представляли собой соотношения небольших целых чисел (рис. 1). Будем называть такой звукоряд природным.
![]() |
На инструменте, настроенном в соответствии с природным звукорядом, нельзя
было сыграть мелодию, скажем, на тон выше или ниже. Для игры в другой
тональности его надо было перенастраивать. Чтобы
Около VIV вв. до н.э. за решение этой задачи взялся Пифагор
(он был не только учёным, но и блестящим музыкантом). Немного изменив частоты
трёх из семи нот в октаве и точно рассчитав частоты дополнительных звуков, он
обеспечил музыкантам возможность переходить из тональности в тональность
гораздо свободнее. Но
В конце XVII века состоялась новая реформа музыкального строя: немецкий органист Андреас Веркмейстер предложил сделать соотношения между частотами соседних звуков одинаковыми и равными 21/12. С одной стороны, это было полным и окончательным решением проблемы перехода из тональности в тональность без перенастройки инструмента. С другой стороны, после этой реформы в октаве не осталось ни одного целочисленного соотношения каждая нота немного фальшивила. Поэтому многих музыкантов поначалу возмутило предложение Веркмейстера. Но в конце концов соображения удобства перевесили, и такой звукоряд (называемый темперированным) используется и по сей день.
После изобретения Веркмейстером своего звукоряда прошло почти три столетия, когда не менее великий изобретатель, сэр Клайв Синклер, выпустил свой знаменитый ZX Spectrum 128 с музыкальным сопроцессором.
Частота на выходе каждого из трёх имеющихся в сопроцессоре генераторов тона получается путём деления тактовой частоты на 16 и последующего деления на целое число в диапазоне 14095. Это число называется коэффициентом деления.
Ниже приведены формулы, связывающие тактовую частоту сопроцессора (CLK), коэффициент деления (k) и частоту на выходе (F). Пользуясь ими, можно вычислить каждую из этих трёх величин по двум другим, значения которых известны.
| F = CLK/(16 k) | (*) | |
| k = [CLK/(16 F) + 0.5] | (**) | |
| CLK = 16 F k | (***) |
Во всех музыкальных редакторах для ZX Spectrum, которые я видел (Sound
Tracker, ASC Sound Master, Pro Tracker, Pro Sound Creator и др.)
используется темперированный звукоряд. Сразу же, не производя
Погрешность можно уменьшить, увеличивая тактовую частоту сопроцессора [4], но полностью избавиться от неё принципиально невозможно.
В темперированном звукоряде и так каждая нота немного фальшивит, а когда заложенная в нём погрешность складывается с погрешностью его реализации на сопроцессоре (табл. 1), результат не может удовлетворить даже невзыскательного слушателя.
| Нота | Частота, Гц | ||
|---|---|---|---|
| Натуральный звукоряд |
Темперированный звукоряд |
Наилучшее приближение к темперированному звукоряду для AY (YM) при CLK=1,75 МГц |
|
| A1 | 440,0 | 440,0 | 439,3 |
| B1 | 495,0 | 493,9 | 494,9 |
| C2 | 528,0 | 523,3 | 523,3 |
| D2 | 594,0 | 587,3 | 588,0 |
| E2 | 660,0 | 659,3 | 658,9 |
| F2 | 704,0 | 698,5 | 696,7 |
| G2 | 792,0 | 784,0 | 781,3 |
| A2 | 880,0 | 880,0 | 882,1 |
Любые две частоты, сформированные сопроцессором, относятся друг к другу как целые числа. Да ведь это как раз то, что нужно для реализации природного звукоряда!
Посмотрим на рис. 1 и, учитывая, что между коэффициентом деления и частотой на выходе сопроцессора существует обратная зависимость, выпишем соотношения коэффициентов деления для нот от «ля» одной октавы до «ля» следующей октавы:
| ka/kb | = | 9/8, | (1) | |
| kb/kc | = | 16/15, | (2) | |
| kc/kd | = | 9/8, | (3) | |
| kd/ke | = | 10/9, | (4) | |
| ke/kf | = | 16/15, | (5) | |
| kf/kg | = | 9/8, | (6) | |
| kg/ka' | = | 10/9. | (7) |
Попробуем подобрать минимальный набор коэффициентов ka, kb, , kg, который удовлетворял бы этим соотношениям.
Коэффициенты, как мы помним, должны быть целыми. Чтобы выполнялось равенство (1), возьмём ka=9, kb=8. Из (2) следует, что kb должно делиться на 16. Удвоим начальные значения первых двух коэффициентов, что не изменит соотношения между ними: ka=18, kb=16. Тогда kc=15. Но kc должно делиться на 9 этого требует условие (3). Утроим коэффициенты: ka=54, kb=48, kc=45. Тогда kd=45*8/9=40. Из равенства (4) получаем ke=40*9/10=36. Из (5) следует, что ke должно делиться на 16. Для этого умножим коэффициенты на четыре: ka=216, kb=192, kc=180, kd=160, ke=144. Тогда kf=144*15/16=135. Ну и, наконец, kg=135*9/10=120.
Итак, требуемый набор коэффициентов деления получен: 216, 192, 180, 160, 144, 135, 120. Первый коэффициент, ka, соответствует ноте «ля» именно она раньше считалась первой нотой октавы. В буквенных обозначениях нот (A, B, C, D, E, F, G) это сохранилось до сих пор. Сохранилась и эталонная нота «ля» первой октавы (440 Гц). Теперь принято начинать октаву с ноты «до». В соответствии с этим представим набор коэффициентов так, чтобы он начинался с kc, а ka и kb разделим на два и переместим в конец: 180, 160, 144, 135, 120, 108, 96.
Так как этот набор наименьший, он определяет коэффициенты для самой высокой октавы, которая будет звучать без искажений. Удваивая эти коэффициенты, мы получим значения, соответствующие более низким октавам. Напротив, последовательно деля их на два, мы получим значения, соответствующие более высоким октавам, но каждый раз, когда деление нельзя будет произвести нацело, будет возникать погрешность.
Произведём вышеописанные действия, учитывая, что коэффициенты не должны выходить за пределы диапазона 14095. Округлять получающиеся при делении дробные значения до ближайшего целого числа пока не будем, чтобы избежать накопления погрешности. Вычисленные значения сведём в таблицу.
| 3840 | 3456 | 3072 | ||||
| 2880 | 2560 | 2304 | 2160 | 1920 | 1728 | 1536 |
| 1440 | 1280 | 1152 | 1080 | 960 | 864 | 768 |
| 720 | 640 | 576 | 540 | 480 | 432 | 384 |
| 360 | 320 | 288 | 270 | 240 | 216 | 192 |
| 180 | 160 | 144 | 135 | 120 | 108 | 96 |
| 90 | 80 | 72 | 67,5 | 60 | 54 | 48 |
| 45 | 40 | 36 | 33,75 | 30 | 27 | 24 |
| 22,5 | 20 | 18 | 16,875 | 15 | 13,5 | 12 |
| 11,25 | 10 | 9 | 8,4375 | 7,5 | 6,75 | 6 |
| 5,625 | 5 | 4,5 | 4,2188 | 3,75 | 3,375 | 3 |
| 2,8125 | 2,5 | 2,25 | 2,1094 | 1,875 | 1,6875 | 1,5 |
| 1,4063 | 1,25 | 1,125 | 1,0547 |
Теперь, учитывая, что коэффициенты должны быть целыми, выполним округление. Округлённые значения пометим подчёркиванием. Заодно выделим жирным шрифтом значения, кратные 16 (зачем это нужно, я объясню в дальнейшем).
| C | D | E | F | G | A | B |
|---|---|---|---|---|---|---|
| 3840 | 3456 | 3072 | ||||
| 2880 | 2560 | 2304 | 2160 | 1920 | 1728 | 1536 |
| 1440 | 1280 | 1152 | 1080 | 960 | 864 | 768 |
| 720 | 640 | 576 | 540 | 480 | 432 | 384 |
| 360 | 320 | 288 | 270 | 240 | 216 | 192 |
| 180 | 160 | 144 | 135 | 120 | 108 | 96 |
| 90 | 80 | 72 | 68 | 60 | 54 | 48 |
| 45 | 40 | 36 | 34 | 30 | 27 | 24 |
| 23 | 20 | 18 | 17 | 15 | 14 | 12 |
| 11 | 10 | 9 | 8 | 8 | 7 | 6 |
| 6 | 5 | 5 | 4 | 4 | 3 | 3 |
| 3 | 3 | 2 | 2 | 2 | 2 | 2 |
| 1 | 1 | 1 | 1 |
Что можно сказать, взглянув на эту таблицу? Она содержит 84 значения коэффициентов, соответствующие 84 нотам. Это 11 полных октав и две неполные. 59 нот звучат абсолютно точно, а оставшиеся 25 фальшивые. В начале таблицы имеется непрерывный участок из 41 ноты, звучащих без погрешностей. Это почти шесть октав такого диапазона достаточно для проигрывания значительной части музыкальных произведений.
Зачем мы отмечали в таблице значения, кратные 16? Вспомним, что сопроцессор
может формировать звуки не только с помощью генераторов тона, но и с помощью
генератора огибающей. Частота тона зависит от делителя частоты тона, а частота
огибающей, соответственно, от делителя частоты огибающей. Разница в том, что
при работе генератора огибающей тактовая частота вначале делится не на 16, а
на 256. Как видим, частота огибающей регулируется более грубо, нежели частота
тона.
Определимся теперь с тактовой частотой сопроцессора. Её нетрудно вычислить, зная, что частота ноты «ля» первой октавы равна 440 Гц, зная коэффициент деления, соответствующий этой ноте, и используя формулу (***).
Напомню, что октавы именуются в таком порядке (снизу вверх): субконтроктава, контроктава, большая, малая, первая, вторая, третья, четвёртая и пятая. Первая октава, считающаяся наиболее употребительной, находится примерно в середине звукоряда.
Где в таблице находится коэффициент, соответствующий ноте «ля» первой октавы? Очевидно, в столбце «A» именно таково буквенное обозначение этой ноты. А вот в какой строке? Строку мы можем выбрать сами, руководствуясь тем, чтобы используемые в мелодии ноты попали на область значений с нулевой погрешностью.
Для примера рассчитаем тактовую частоту сопроцессора, если первой октаве соответствует пятая сверху строка таблицы:
Если бы мы выбрали не пятую, а четвёртую строку сверху, то значение CLK было бы вдвое больше. А если шестую строку сверху, то вдвое меньше.
При этой тактовой частоте мы сможем играть в чистом до мажоре и ля миноре. Чтобы играть в других тональностях, тактовую частоту придётся менять.
Если мы хотим иметь возможность проиграть любую мелодию, начиная с любого звука октавы (о чём, собственно, и мечтали древние музыканты), и если считать базовым значением тактовой частоты 1520640 Гц, то нам понадобится такой набор частот:
| Тональность | CLK, Гц |
|---|---|
| до мажор | 1520640 |
| ре мажор | 1520640*9/8 = 1710720 |
| ми мажор | 1710720*10/9 = 1900800 |
| фа мажор | 1900800*16/15 = 2027520 |
| соль мажор | 2027520*9/8 = 2280960 |
| ля мажор | 2280960*10/9 = 2534400 |
| си мажор | 2534400*9/8 = 2851200 |
| ля минор | 1520640# |
| си минор | 1520640*9/8 = 1710720# |
| до минор | 1710720*16/15 = 1824768 |
| ре минор | 1824768*9/8 = 2052864 |
| ми минор | 2052864*10/9 = 2280960# |
| фа минор | 2280960*16/15 = 2433024 |
| соль минор | 2433024*9/8 = 2737152 |
Итого одиннадцать различных частот, так как три значения повторяются в таблице дважды (они помечены символом «#»). Для того, чтобы можно было смещать диапазон нот с нулевой погрешностью на октаву вверх или вниз, подстраиваясь под конкретную мелодию, потребуются ещё вдвое большие и вдвое меньшие значения.
Если требуется исполнять произведения во всех двадцати четырёх тональностях двенадцати мажорных и двенадцати минорных видимо, наиболее оптимально будет сделать так, чтобы для каждой следующей тональности тактовая частота была в 21/12 раза больше, чем для предыдущей. При этом потребуется всего двенадцать различных значений CLK:
| Тональность | CLK, Гц |
|---|---|
| до мажор, ля минор | 1520640 |
| 1611062 | |
| ре мажор, си минор | 1706861 |
| 1808356 | |
| ми мажор, | 1915886 |
| фа мажор, ре минор | 2029811 |
| 2150510 | |
| соль мажор, ми минор | 2278386 |
| 2413866 | |
| ля мажор, | 2557401 |
| 2709472 | |
| си мажор, | 2870586 |
Как видим, для проигрывания музыки в различных тональностях при
использовании натурального звукоряда с нулевой погрешностью требуется
аппаратная доработка, позволяющая изменять тактовую частоту сопроцессора.
(Нечто подобное было описано в [4], только в нашем случае
возможных значений CLK должно быть не два, а больше, и переключение
должно осуществляться не вручную, а посредством записи определённого значения
в определённый порт.) Если же вы не собираетесь изменять эту частоту, и она
равна 1750000 Гц (как в моём «Пентагоне», да и во многих
других моделях
С помощью чего вы будете сочинять и проигрывать музыку? Очевидно, с помощью музыкального редактора. Наиболее популярным редактором в настоящее время является Pro Tracker (далее PT) о нём и поговорим.
Доступный в PT диапазон восемь октав: от контроктавы до пятой октавы. В редакторе они обозначаются цифрами от 1 до 8. Сопоставим им первые восемь полных строк из таблицы 3. В этих строках подчёркнуты лишь пять значений из 56 а значит, только пять нот будут фальшивыми: F6, F7, C8, F8 и A8 (номера октав здесь указаны так, как принято в PT). Все остальные ноты будут звучать с нулевой погрешностью.
Информация о том, какой коэффициент деления соответствует каждой ноте, содержится внутри PT в специальной таблице (её называют частотной). Под каждое значение коэффициента отводится два байта; количество коэффициентов 12*8=96, отсюда размер таблицы 192 байта.
Создадим нужную нам частотную таблицу с помощью ассемблера. Значения коэффициентов, как уже упоминалось, будем брать из первых восьми полных строк таблицы 3. Так как при использовании натурального звукоряда дополнительные звуки (C#, D#, F#, G#, A#) не нужны, сделаем соответствующие им коэффициенты нулевыми.
ORG #8000 DW 2880,0,2560,0,2304,2160,0,1920,0,1728,0,1536 DW 1440,0,1280,0,1152,1080,0,960,0,864,0,768 DW 720,0,640,0,576,540,0,480,0,432,0,384 DW 360,0,320,0,288,270,0,240,0,216,0,192 DW 180,0,160,0,144,135,0,120,0,108,0,96 DW 90,0,80,0,72,68,0,60,0,54,0,48 DW 45,0,40,0,36,34,0,30,0,27,0,24 DW 23,0,20,0,18,17,0,15,0,14,0,12 |
Этот текст надо откомпилировать и записать объектный код в файл
«table.C». Ну а если вы не умеете пользоваться ассемблером, можете
создать файл с частотной таблицей в любом
#0000: 400B 0000 000A 0000 0009 7008 0000 8007 #0010: 0000 C006 0000 0006 A005 0000 0005 0000 #0020: 8004 3804 0000 C003 0000 6003 0000 0003 #0030: D002 0000 8002 0000 4002 1C02 0000 E001 #0040: 0000 B001 0000 8001 6801 0000 4001 0000 #0050: 2001 0E01 0000 F000 0000 D800 0000 C000 #0060: B400 0000 A000 0000 9000 8700 0000 7800 #0070: 0000 6C00 0000 6000 5A00 0000 5000 0000 #0080: 4800 4400 0000 3C00 0000 3600 0000 3000 #0090: 2D00 0000 2800 0000 2400 2200 0000 1E00 #00A0: 0000 1B00 0000 1800 1700 0000 1400 0000 #00B0: 1200 1100 0000 0F00 0000 0E00 0000 0C00
Ещё в PT есть так называемая таблица огибающих (она нужна только при написании музыки проигрывать уже написанную можно и без неё). В ней содержатся значения коэффициентов из частотной таблицы, делённые на восемь. Каждое значение хранится в одном байте; если оно не умещается в байте (т.е. больше 255), то в таблицу помещается число 255. Вся таблица занимает 96 байтов.
Заметим, что деление на восемь соответствует смещению на три октавы вверх. Следовательно, мы можем взять значения для таблицы огибающих из таблицы 3, сместившись в ней на три строки вниз от первой полной строки.
Ассемблерный текст, описывающий таблицу огибающих, будет выглядеть следующим образом:
ORG #8000 DB 255,0,255,0,255,255,0,240,0,216,0,192 DB 180,0,160,0,144,135,0,120,0,108,0,96 DB 90,0,80,0,72,68,0,60,0,54,0,48 DB 45,0,40,0,36,34,0,30,0,27,0,24 DB 23,0,20,0,18,17,0,15,0,14,0,12 DB 11,0,10,0,9,8,0,8,0,7,0,6 DB 6,0,5,0,5,4,0,4,0,3,0,3 DB 3,0,3,0,2,2,0,2,0,2,0,2 |
Полученный после компиляции объектный код (его дамп приведён ниже) запишем в файл «envelope.C».
#0000: FF00 FF00 FFFF 00F0 00D8 00C0 B400 A000 #0010: 9087 0078 006C 0060 5A00 5000 4844 003C #0020: 0036 0030 2D00 2800 2422 001E 001B 0018 #0030: 1700 1400 1211 000F 000E 000C 0B00 0A00 #0040: 0909 0008 0007 0006 0600 0500 0504 0004 #0050: 0003 0003 0300 0300 0202 0002 0002 0002
К сожалению, в PT (впрочем, как и в любом другом известном мне музыкальном редакторе для ZX Spectrum) не предусмотрена возможность использования частотной таблицы, определённой пользователем. В нём имеются лишь четыре заранее рассчитанные таблицы для различных тактовых частот сопроцессора. Можно заменить одну из них на нужную нам, но для этого придётся изрядно потрудиться. Рассмотрим этот процесс подробнее.
Нам потребуется Pro Tracker 3.51 (это последняя версия на момент написания
этой статьи; у вас может быть и другая версия в этом случае
действуйте по аналогии),
Чтобы избежать повреждения
Теперь из четырёх имеющихся в редакторе таблиц надо выбрать ту, которую мы будем заменять на свою. Пусть это будет таблица «1.750000 Hz» (в PT 3.4 она называлась «ASM OR PSC»).
Чтобы осуществить замену, надо знать, где расположена эта таблица. А для этого, в свою очередь, надо знать, как она выглядит, с какой последовательности байтов она начинается.
Известно, что в модуле, откомпилированном с плеером, частотная таблица находится по смещению #200 от начала. Создадим такой модуль, содержащий интересующую нас таблицу. Для этого сразу после запуска PT установим в setup параметр «Frequency table» равным 1.750000 Hz (по умолчанию именно это значение там и стоит), выберем пункт «Compiler» и в появившемся окне выберем «Save compiled song». Запишем модуль, например, под именем «test».
Затем с помощью BestView просмотрим дамп этого модуля. По смещению #200 там будет следующее:
#0200: 100D 550C A40B FC0A 5F0A CA09 3D09 B808 #0210: 3B08 C507 5507 EC06 8806 2A06 D205 7E05 #0220: 2F05 E504 9E04 5C04 1D04 E203 AB03 7603 ...... .......................................
Приступим к поиску этой таблицы в PT. Нажмём комбинацию клавиш «CS+A» на файле «PTv3.51z». Из появившегося списка распознанных блоков нас интересует «p_blk_01» таблица находится именно там. Нажав «Z» на этом упакованном блоке, посмотрим его параметры:
![]() |
Далее с помощью клавиши «L» проскроллируем файловую панель
вправо, чтобы узнать
Нажав «SS+Enter», распакуем блок на диск под именем «unpack1». Выведем дамп распакованного блока с помощью «CS+Enter» и, зная, с какой последовательности байтов начинается таблица, попробуем её найти. Как выясняется, она находится по смещению #47F.
Таблицу огибающих легко отыскать, зная, что несколько первых байтов в ней равны #FF, а следующие байты соответствуют элементам частотной таблицы, только на три октавы выше. Она находится по смещению #3BF.
Ну что ж, можно заменять эти таблицы на свои. Запускаем STS и загружаем распакованный блок на адрес #8000. Частотную таблицу загрузим из файла «table.C» на адрес #8000+#47F=#847F. Таблицу огибающих загрузим из файла «envelope.C» на адрес #8000+#3BF=#83BF. Запишем изменённый блок под тем же именем «unpack1», start=#8000, length=#2F55. Осталось упаковать его и записать внутрь PT.
Запускаем HRUST, упаковываем блок без распаковщика и записываем его в файл
с именем «unpack1*.C». Если длина упакованного блока в секторах не
превосходит #11 секторов, то всё в порядке. В нашем случае это так и есть. А
вот если блок оказался длиннее (скажем, если вы вставляли
Запишем упакованный блок внутрь файла «PTv3.51z».
Всё! Теперь таблица «1.750000 Hz» в редакторе ваша! Можете запустить редактор и оценить звучание.
Уже переделанный таким образом Pro Tracker 3.51 вы можете получить, обратившись ко мне по одному из указанных в начале статьи адресов.
Для игры в до мажоре или ля миноре тактовая частота сопроцессора, как мы уже рассчитывали, будет равна 1520640 Гц. Меняя её, как описано в предыдущем разделе, вы сможете играть в других тональностях, используя те же клавиши, что, на мой взгляд, весьма удобно. Можно, впрочем, для каждой тональности хранить свой экземпляр редактора со сдвинутыми соответствующим образом таблицами.
Да, кстати: для изменения тактовой частоты сопроцессора при работающем PT, очевидно, придётся либо использовать ручной переключатель, либо, в случае изменения частоты путём записи значения в порт, доработать PT, чтобы эта функция была в нём реализована.
Частоты нот в каждой следующей октаве вдвое больше, чем в предыдущей, а коэффициенты деления, соответственно, вдвое меньше. Таким образом, если известны значения коэффициентов для нот самой нижней октавы, делением на два легко получить их значения для следующих октав. Это можно использовать для того, чтобы не хранить частотную таблицу в программе, а строить её с помощью ассемблерной процедуры. При этом мы получим ощутимый выигрыш в длине программы за счёт того, что процедура построения таблицы и исходные данные для неё будут занимать меньше места, чем сама таблица.
Ниже приведён текст этой процедуры. Входные параметры: в HL указывается адрес, по которому расположены коэффициенты для нот нижней октавы (они хранятся в специальном формате с повышенной точностью подробнее см. ниже), а в DE указывается адрес, по которому будет располагаться построенная таблица. Длина процедуры 40 байтов, длина исходных данных 12*2=24 байта. По сравнению с длиной частотной таблицы (192 байта) это весьма мало.
MAKE_FT LD B,12
M1 PUSH BC
LD C,(HL)
INC HL
PUSH HL
LD B,(HL)
PUSH DE
EX DE,HL
LD DE,23
LD XH,8
M2 SRL B
RR C
LD A,C
ADC A,D ;=ADC 0
LD (HL),A
INC HL
LD A,B
ADC A,D ;=ADC 0
LD (HL),A
ADD HL,DE
DEC XH
JR NZ,M2
POP DE
INC DE
INC DE
POP HL
INC HL
POP BC
DJNZ M1
RET
Обратите внимание на то, как осуществляется деление на два. Если делать его простым сдвигом, отбрасывая выдвинутый разряд, процедуру можно было бы сильно упростить. Но абсолютная погрешность при этом достигала бы единицы младшего разряда. Чтобы минимизировать погрешность, деление производится с округлением: если выдвинутый при сдвиге бит равен единице (а значит, дробная часть результата больше или равна 0,5), к результату прибавляется единица; если же выдвинутый бит был равен нулю (дробная часть меньше 0,5), результат остаётся каким был. Как видим, в этом случае абсолютная погрешность не будет превосходить половины младшего разряда, т.е. будет вдвое меньше.
Округление производится непосредственно при записи результата в память. В последующих делениях на два участвует неокруглённое значение, чтобы избежать накопления погрешности.
Значения коэффициентов для нижней октавы хранятся с повышенной точностью с одним дополнительным разрядом: если точное значение коэффициента k1, то хранится значение [k1*2].
Построенная с помощью такой процедуры частотная таблица будет полностью совпадать с наилучшим возможным приближением к теоретически рассчитанным значениям коэффициентов деления.
Рассмотрим использование этой процедуры на примере: попробуем создать частотную таблицу для натурального звукоряда при тактовой частоте сопроцессора 1,75 МГц. Как мы помним, самая низкая октава в PT контроктава; вычислим частоты нот этой октавы, учитывая, что они в восемь раз меньше, чем частоты соответствующих нот первой октавы и в шестнадцать раз меньше, чем частоты нот второй октавы а их значения мы возьмём из табл. 1.
| Fc | = 528/16 | = 33 Гц, |
| Fd | = 594/16 | = 37,125 Гц, |
| Fe | = 660/16 | = 41,25 Гц, |
| Ff | = 704/16 | = 44 Гц, |
| Fg | = 792/16 | = 49,5 Гц, |
| Fa | = 440/8 | = 55 Гц, |
| Fb | = 495/8 | = 61,875 Гц. |
Теперь по формуле (**) вычислим соответствующие этим нотам значения коэффициентов, но округления выполнять не будем.
| kc | = 3314,3939, |
| kd | = 2946,1279, |
| ke | = 2651,5152, |
| kf | = 2485,7955, |
| kg | = 2209,596, |
| ka | = 1988,6364, |
| kb | = 1767,6768. |
Исходные данные для процедуры построения таблицы удобно получить, умножив целую часть этих коэффициентов на два и прибавив 1, если дробная часть больше или равна 0,5:
TABL_TEST DW 3314*2+0
DW 0
DW 2946*2+0
DW 0
DW 2651*2+1
DW 2485*2+1
DW 0
DW 2209*2+1
DW 0
DW 1988*2+1
DW 0
DW 1767*2+1
Ну а само построение осуществится следующими командами (в предположении, что таблица будет сформирована с адреса #8000):
LD HL,TABL_TEST
LD DE,#8000
CALL MAKE_FT
Если вы захотите использовать эту частотную таблицу при написании музыки в PT, то вам ещё понадобится рассчитать таблицу огибающих. Вот как это можно сделать с наименьшими затратами времени. Если заменить в процедуре MAKE_FT команду LD XH,8 на LD XH,11, то с адреса (DE+72) будут сформированы 96 значений коэффициентов для таблицы огибающих. Правда, после этого их ещё надо «уплотнить», ведь, как уже упоминалось в предыдущем разделе, каждый коэффициент должен храниться в одном байте, и значения, большие 255, должны быть заменены на 255. Это удобно выполнить с помощью нижеприведённой процедуры. Входные параметры: HL адрес частотной таблицы, увеличенный на 72; DE адрес, по которому будет сформирована таблица огибающих.
LD B,96
M1 LD A,(HL)
INC HL
INC (HL)
DEC (HL)
JR Z,M2
LD A,#FF
M2 LD (DE),A
INC HL
INC DE
DJNZ M1
RET
Между прочим, в [1] приводится мнение, что «электронный» оттенок компьютерной музыки во многом обусловлен именно строгой темперацией, которую проходят в компьютере любые инструменты. Попробуйте проверить, так ли это. Напишите модуль с использованием полученной таблицы, а потом запишите его в двух вариантах: откомпилированным с плеером и без плеера. При проигрывании в BestView модуля, откомпилированного без плеера, будет использована стандартная темперированная частотная таблица, а при проигрывании модуля, откомпилированного с плеером, будет использована таблица, взятая непосредственно из модуля. Обе таблицы рассчитаны для одной и той же тактовой частоты сопроцессора (1,75 МГц), что обеспечит подходящие условия для сравнения звучания.
|
Другие мои статьи об
|