Извлечение нот из музыкального WAV файла

  Переложение музыкальной записи на ноты обсуждается в интернете. Для этого есть готовые программы -
http://www.akoff.com/index_rus.html
http://www.softkey.info/reviews/review689.php
  Результат получается в MIDI формате, и, если Вы с ним работаете, то можете оформить напетую Вами мелодию в полноценное музыкальное произведение. Но можно и просто извлечь ноты, не напрягая свой музыкальный слух.

  И, разумеется, подобную программу мне захотелось сделать самому. Прежде всего из любопытства. Чтобы узнать, как это всё устроено, но также и для собственных практических целей. Кроме того, я хочу показать, как этого можно достичь, не используя профессиональные программы, а используя простые средства Турбо Бейсика.
  Результат получился у меня ничуть не хуже.


   ПРИНЦИП АНАЛИЗА МУЗЫКАЛЬНОЙ ЗАПИСИ

  Готовая музыка достаточно хаотична, в ней имеется многоголосие и аккорды, а тембр звучащих инструментов привносит обертоны. Кроме того певец, если используется запись голоса, может петь и не в ноты. Не Ми или Фа с их ожидаемыми частотами, а где-нибудь между Ми и Фа.
  Но со всем этим, как оказывается, можно справится, используя достаточно простой алгоритм.

  Идея очень простая (никаких Фурье анализов !) - сделаем осциллятор, и пусть звук его раскачивает. Нот много - на четыре октавы с полутонами их 48. Сделаем 48 осцилляторов, посмотрим, какие из них сильнее раскачиваются, и отметим эти ноты.
  Поём не в ноты? Ну, тогда раскачиваются два соседних осциллятора с приблизительно равной амплитудой.

  Итак, делаем осциллятор - груз массой m на пружине жёсткости K.
  ( вспоминайте, вспоминайте второй закон Ньютона ))
  В начальный момент времени груз находится в положении равновесия - его координата равна нулю X=0, и его скорость также равна нулю V=0.
  Приходит звук в виде олицетворяющей силу амплитуды A, и начинает груз раскачивать. Семплы со своими положительными или отрицательными амплитудами "ударяют" в груз то справа, то слева. Попадут ли эти удары в резонанс?

  Ясно, что если силовое воздействие на осциллятор будет долгое время попадать в такт, то осциллятор раскачается очень прилично. Но мы не будем вводить диссипативной функции трения, пусть лучше осциллятор раскачивается, предоставленный воздействию звука некоторое время, потом мы его остановим, проанализируем результаты, и запустим снова.
  Таким образом, за время 1 сек мы сделаем с помощью нашего осциллятора несколько проб. 
  Комплект проб - sample kit. Введём переменную KIT - число проб в секунду. Время одной пробы будет равно 1/KIT, а число семплов, приходящихся на пробу - 32000/KIT (я работаю со скоростью раздачи 32000 семплов в секунду).
  Удобно, если на пробу приходится целое число семплов. Из этого соображения будем выбирать значение KIT из ряда 4 5 8 10 16 и 20. Чем меньше KIT, тем точнее мы сможем выделить звук по частоте на фоне других. Чем больше KIT, тем более короткие по длительности звучания ноты мы сможем подвергнуть анализу.

  Итак, запишем второй закон Ньютона для нашего осциллятора в таком виде -

    A/m - (K/m)*X = X" = dV/dT

  введём переменную Km, равную отношению K/m, и выразим её через частоту резонансного колебания. Возьмём к примеру, F=320 Гц. Тогда

  Km = (F*2*Пи)*(F*2*Пи) = 4042590 ньютон/м*кг

не пугайтесь такого большого числа, чтобы попасть в резонанс со звуком, при массе груза в 1кг жёсткость "пружины" должна быть очень большой - даже при смещении на 10 мкм она создаёт усилие в 4кг силы. Это не пружина, а скорее колокол! Но неважно, мы только математикой интересуемся, поэтому полагаем, что смещение X можно взять для удобства вычислений где-то около 1 (1 метр).
  Раскачивающую силу возьмём на порядок меньше упругой силы, а поскольку обычное характерное значение амплитуды звука в не очень громких семплах составляет 4000, то в качестве множителя 1/m возьмём число 100 (масса груза 10 грамм).


   АЛГОРИТМ ВЫЧИСЛЕНИЙ

  С физикой закончили, давайте писать алгоритм раскачивания нашего осциллятора -

  dT=1/32000
  X=0 : V=0 : XM=0 'здесь мы будем фиксировать максимальное отклонение
  FOR I=1 TO 32000/KIN
   A=AM(I) 'извлекаем амплитуду из массива, в котором хранятся амплитуды семплов 
   dV=(A*100-Km*X)*dT : V=V+dV
    ' V=V*.999 если хочется, то этим можно учесть трение
    'но, как уже говорилось, трение лучше не вводить, оно притупляет резонанс
   X=X+V*dT : IF X>XM THEN XM=X
  NEXT I

  так, в последовательных итерациях, наш осциллятор постепенно раскачивается. В отсутствии резонанса XM не превышает 1. В присутствии резонанса максимальная амплитуда составляет от 5 до 20 в зависимости от длительности пробы.
 
  Чтобы перейти ко множеству осцилляторов, нужно заменить единичные переменные X, V и XM на соответствующие массивы. Массив понадобится и для множителя Km. При равномерной темперации различие между частотами полутонов составляет exp(ln(2)/12)=1.0594631, соответственно этому меняется и множитель Km.

  Но вот, мы пробу звука рассчитали и получили массив максимальных отклонений XM(J) для осцилляторов, настроенных на разные частоты. Что делать дальше ?
  Звук может быть громким или тихим, соответствующие и амплитуды будут, мы же хотим найти доминирующие в спектре амплитуды безотносительно к громкости звука. Поэтому проведём нормировку значений XM(J). Найдём ноту с XMM - наибольшим значением  среди XM(J), и найдём XMM1 - наибольшее XM из двух, примыкающих к найденной ноте.
  И приняв, что должно быть XMM+XMM1=10, проведём нормировку всего массива XM(J).

  Теперь мы можем выделять в массиве доминанты со значениями 9 или 8, и менее доминирующие ноты со значениями 7,6 и 5. А что же остальные? Некие значения XM имеются на всех осцилляторах.
  Чтобы получить наглядную картину, проведём дискриминацию - положим XM=0 всюду, где не достигнут некий пороговый уровень DNo. Положим например DNo=4, меньшие значения XM дискриминируем, а информацию об остальных выведем в текстовый файл в том наглядном виде, который показан на рисунке к статье.
  Чтобы символы в файле шли "стройными рядами", возьмите шрифт Lucida Console.


   ОБСУЖДЕНИЕ РЕЗУЛЬТАТОВ

  Вертикальные линии на рисунке - чёрные клавиши.
  Между ними и на них цифрами указаны амплитуды, соответствующие найденным нотам доминантам, или их сильным обертонам. Из рисунка видно, что между исходным нотным текстом и расшифровкой его записи имеется хорошее соответствие.
 
  Исходный текст - начало Чаконы И.С.Баха, сделанное синтезированными звуками альта. Тембр записи сложный, тембр меняется от ноты к ноте, форма колебаний непостоянна и изрезана - какая она, можно посмотреть здесь http://www.proza.ru/2016/03/08/2244
  Тем не менее программа с заданием прекрасно справилась. На рисунке представлена расшифровка последних двух тактов строки - с 10-й по 17-ю секунду. Видно, что запись демонстрирует правильные ноты.
  Правильные, да не совсем. Доминирующие в расшифровке ноты лежат на октаву выше. Это результат характерного тембра альта и формы синтезированного звука - колебание в своём начале имеет характерный острый пичок шириной примерно в четверть периода. Этот пичок и раскачивает вторую гармонику основного тона. Сам основной тон тоже присутствует на расшифровке. Он хоть и оказывается выше уровня дискриминации, который был взят специально пониже, но основной тон не столь очевиден, как его вторая гармоника.
  Запись можно прослушать здесь - https://yadi.sk/d/f5588riKuJyvZ
К записи претензий нет, на звук альта похоже, и тон слышится низкий. Но и обертоны, как оказывается, очень сильны.

  Ничего не было сказано о паузах. Паузы могут присутствовать в записи, и надо, чтобы программа не искала звук там, где его нет. Для этого используется дискриминация пробы по величине средней амплитуды - если среднее абсолютное значение амплитуды семплов оказывается ниже значения DAc=100, то на этом месте расшифровки нотных отметок не делается.
  Значения KIN, и уровни дискриминации DAc и DNo выставляются так, как это оказывается наиболее удобным при нотной расшифровке записи.


   ТЕКСТ ПРОГРАММЫ

'N11.BAS анализ нотного спектра записи

DIM AM(15000) : DIM Km(50) : DIM X(50) : DIM V(50) : DIM XM(50) : DIM FM(50)
 PI=3.14159265 : MF=1.0594631
FFM=0  '1 - делается выравнивание по частоте, если 0 - нет
KIT=8   ' 1sec/4 5 8 10 16 or 20 = число проб звука за одну секунду
DAc=100 : DNo=4 'дискриминаторы амплитуды и значимости звука

GOSUB 100
OPEN "NS.TXT" FOR OUTPUT AS #2
OPEN "B",#1,"r.wav" : SEEK #1,44 : T=0 : NT=1
  PRINT "======";
10 S$=INKEY$ : IF S$=" " THEN PRINT " Exit" : CLOSE #1,#2 : STOP
  IF LOF(1)<LOC(1)+NAM*2+2 THEN PRINT " Ok" : CLOSE #1,#2 : STOP
  NT=NT+1
  IF NT>KIT THEN T=T+1 : NT=1 : PRINT #2,T : PRINT T; : IF POS>70 THEN PRINT
  FOR I=0 TO NX+1 : X(I)=0 : V(I)=0 : XM(I)=0 : NEXT I
   Ac=0 : FOR I=1 TO NAM : GET$ #1,2,S$ : A=CVI(S$)
   Ac=Ac+ABS(A) : AM(I)=A : NEXT I
  Ac=Ac/NAM : IF Ac<DAc THEN PRINT #2,KLAVA$ : GOTO 10 'pause
  FOR I=1 TO NAM : A=AM(I)
   FOR J=1 TO NX : dV=(A*100-Km(J)*X(J))*dT
    V(J)=V(J)+dV : X(J)=X(J)+V(J)*dT 
   IF X(J)>XM(J) THEN XM(J)=X(J)
  NEXT J : NEXT I
  XMM=0 : FOR J=1 TO NX : IF XM(J)*FM(J)>XMM THEN XMM=XM(J)*FM(J) : JM=J
  NEXT J : XMM1=XM(JM-1) : IF XM(JM+1)>XMM1 THEN XMM1=XM(JM+1)
          MXM=10/(XMM+XMM1*FM(JM)) : KL$=KLAVA$
  FOR J=1 TO NX : A=MXM*XM(J)*FM(J) : IF A<DNo THEN A=0 : ELSE A=INT(A+.5)
    IF A>9 THEN A=9
    IF A>0 THEN S$=CHR$(48+A) : MID$(KL$,J+4)=S$
  NEXT J
  PRINT #2,KL$
GOTO 10

'====== тест работы программы
  PRINT #2,"=======";NAM;Ac
  FOR J=1 TO NX : PRINT #2,J;FM(J);XM(J) : NEXT J
  CLOSE #1,#2 : PRINT "Ok" : STOP

'====== предварительные установки
100 NAM=32000/KIT : dT=1/32000 : MF1=MF : IF FFM=0 THEN MF1=1
  FOR I=0 TO 50 : Km(I)=0 : NEXT I
  KmA=440*2*PI : KmA=KmA*KmA : Km(22)=KmA : Z=KmA : FM(22)=1 : Z1=1
  FOR I=1 TO 26 : Z=Z*MF*MF : Km(22+I)=Z : Z1=Z1*MF1 : FM(22+I)=Z1 : NEXT I
  Z=KmA : Z1=1
  FOR I=1 TO 21 : Z=Z/(MF*MF) : Km(22-I)=Z : Z1=Z1/MF1 : FM(22-I)=Z1 : NEXT I
  NX=21+1+26 : L$=CHR$(124) : S$=" "+L$+" "+L$+"  "+L$+" "+L$+" "+L$+" "
  KLAVA$="   ."+S$+S$+S$+S$+"."
RETURN
'===================
  Моно запись со скоростью раздачи 32000 должна быть помещена в файл "r.wav"
Расшифровка, после завершения работы программы, оказывается в файле "NS.TXT"
 
  Можно работать и со стерео файлом WAV со скоростью раздачи 44100 семп/сек
Для этого нужно изменить следующие строки программы:

  KIT=9 ' 1sec/3 4 5 7 9 10 12 15 18 20 21 or 25 = число проб звука за одну секунду
  IF LOF(1)<LOC(1)+NAM*4+4 THEN PRINT " Ok" : CLOSE #1,#2 : STOP
  Ac=0 : FOR I=1 TO NAM : GET$ #1,2,S$ : GET$ #1,2,S2$ : A=CVI(S$)
  100 NAM=44100/KIT : dT=1/44100
звук будет браться с первой дорожки, а вторая дорожка будет пропускаться, но Вы можете сделать по иному.
  Остальное всё то же самое.
  Кстати, посмотрите, на сколько разных частей можно разделить нацело число 44100. Я думаю, именно поэтому оно было взято в качестве стандарта.


   ОБСУЖДЕНИЕ ОСОБЕННОСТЕЙ АЛГОРИТМА

  Естественно, алгоритм не решает всех задач по расшифровке музыкальной записи, но помочь ему можно. Чтобы проверить, как алгоритм работает, нужно поставить апостроф перед оператором GOTO 10 и перейти на тест программы, тестируя запись звука синусоидальной формы некоторой частоты F и амплитуды A.
  В тесте выводятся номера пробных осцилляторов (номер 22 принадлежит частоте 440 Гц), и максимальные амплитуды XM, достигнутые на них.
  Тесты показывают, что почти точно выполняется правило -

  F * KIT * XM / A = C = Const

и отсюда следует, что в нашей расшифровке имеется гипертрофированная чувствительность к колебаниям низкой частоты, и пониженная чувствительность на частоте высокой. Впрочем, может быть это и хорошо, поскольку иначе мы основной тон альта на расшифровке потеряли бы. Но в записи фортепьянных произведений аккомпанемент в расшифровке явно пересиливает мелодию.
  Поэтому просто следует ввести режим выравнивания чувствительности по частоте. Для этого в программе используется флаг FFM, указывающий на необходимость выравнивания, и массив FM(50), содержащий пропорциональные частоте коэффициенты (для F=440 Гц коэффициент равен 1).

  Но это не все сложности с высокими частотами. Тесты показывают стремительное уменьшение в третьей октаве величины C, которая должна бы быть константой.
  Давайте, примем за 100% величину C для ноты Ля малой октавы, F=220 Гц, тогда для других частот получается следующее -

Таблица. Относительные значения величины C при KIT=8-9
второй столбец для записи со скоростью раздачи 32000 семпл/сек
третий - для 44100 семпл/сек

  220 100%
  440 99.1 99.2
  880 96.0 96.5
 1233 76.2 93.3
 1760 29.1 61.4 - Ля третьей октавы

на частотах третьей октавы имеется также выраженная зависимость между C и числом проб в секунду KIT -

С       при значениях KIT
для___ 4    8-9  16-15 30-32
32000 40.3 76.2 93.3
44100 75.0 93.3 96.6      для F=1233 Гц

32000 14.6 29.1 80.2 87.4
44100 27.3 61.4 85.4 96.4   для F=1760 Гц

  Эффект имеется, и вызывает интерес - почему так происходит, и почему имеется явная зависимость чувствительности метода от скорости раздачи семплов в записи?
  Ответ простой - в наших вычислениях мы делаем не бесконечно малые приращения по времени, и когда величина dT отличается от длительности полупериода колебания лишь на порядок, то этого недостаточно, и наш процесс раскачивания стремится не к теоретической резонансной частоте, а к частоте несколько большей.
  И в самом деле - должно быть некое различие в раскачивании качелей не плавно, а рывками.
  При скорости раздачи 32000 резонансная частота оказывается не 1233, а на 0.28% выше, и не 1760, а на 0.45% выше. Малое различие, но мы имеем дело с резонансом, и легко протестировать, что на этих, немного других резонансных частотах величина С и в самом деле является константой.

  Чувствительность алгоритма на высоких частотах никуда не уходит, мы просто промахиваемся мимо резонанса.
  А это уже серьёзно. Кто сказал, что в живом звуке будут именно те частоты, которые мы ожидаем? Скорее всего музыканты будут дудеть "не в ноты", и мы их звуков попросту не обнаружим.
  Выход, к счастью, есть. Давайте использовать для анализа высоких частот короткие пробы, с большим номером KIT. Короткое время анализа приведёт ещё и к тому, что зоны резонансной чувствительности соседних полутонов будут перекрывать друг друга, и звук мы точно не пропустим.
  Однако при этом в распознавании частоты на низких частотах воцарится неопределённость, и это также будет неудобно.
  Разумеется, можно придумать некий комбинированный алгоритм.
  Но этим я заниматься не буду. Известная программа WIDI Recognition System Pro, судя по её описанию, именно на этих принципах и работает.


   ПРИМЕР РАСШИФРОВКИ ЖИВОГО ЗВУКА С МНОГОГОЛОСИЕМ

  Если в расшифровке на рисунке представлено 3 октавы - малая, первая и вторая, то текст программы, и расшифровка ниже показывает 4 октавы - к малой, первой и второй добавлена ещё и третья октава.
  Легко можно было бы добавить и остальные октавы, но чем больше осцилляторов, тем меньше скорость счёта. Расшифровка в 4-х октавах оказывается в 1.7 раз более долгой, чем звучание самой записи. Если запись звучит 30 сек, то расшифровка будет идти 52 сек.
  Если хочется экстренно прервать расшифровку, то нужно нажать клавишу "Пробел".

  Ниже приведён пример расшифровки живого звука - вокал с сопровождением фортепьяно.

  Начало расшифровки показывает негромкий певческий голос с фортепьянным сопровождением в малой октаве той же громкости. В дальнейшем, там где голос звучит громче, фортепьянное сопровождение на расшифровке не видно, оно дискриминируется.
  Но по началу заметно, что звук фортепьяно попадает "не в ноты". Возможно, это связано с тем, что фортепьяно настроено не точно на частоту Ля равную 440 Гц, а на четверть тона выше или ниже. Но возможна и неточность записи. Как бы то ни было, и несмотря на то, что и певческий голос тоже показывает неточное попадание "в ноты", расшифровке это не мешает. Если было не очень понятно, к какой ноте звук принадлежит, я сдвигал его выше. Но можно и ошибиться, ошибки в полтона легко выявляются при прослушивании в программе Пианола.

  Ноты, полученные в расшифровке, я записал с помощью программы Пианола в файл партитуры, и из него, с помощью программы Трио сделал вторичную запись звуков того же вокала.
Результат Вы можете прослушать здесь - https://yadi.sk/d/ZlpRygMvuLH5M
Вначале идёт фрагмент живого вокала, а следом - звуки его расшифровки.

   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | |55  | |  | | |  | |  | | |  | |  | | | .
   . | | 465| 6  | |  |7| |  | |  | | |  | |  | | | .
 1
   . | |  55| |  | |  | | |  | |  | | |  | |  | | | .
   . | |  |5|76  | |  |7| |  | |  | | |  | |  | | | .
   . | |  | |46  | |  | | |  | |  | | |  | |  | | | .
   . | |  | |55  | |  | | |  | |  | | |  | |  | | | .
   . | |  | |46  | |  5 | 6  | |  | | |  | |  | | | .
   . | |  | |46  | 4  55| 4  | |  | | |  | |  | | | .
   . | |  | | |  | |  7 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  |7| |  | |  | | |  | |  | | | .
 2
   . | |  | | |  | |  |7|45  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |8|  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |6 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  6 |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |9|  | | |  | |  | | | .
 3
   . | |  | | |  | |  | | |  |8|  | | |  |5|  | | | .
   . | |  | | |  | |  | | |  |55  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | 7  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | 9  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |55  | | |  |4|  | | | .
   . | |  | | |  | |  | | |  |6|  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |46  | | |  | |  | | | .
   . | |  | | |  | |  | | |  | 6  | | |  | |  | | | .
 4
   . | |  | | |  | |  | | |  |46  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |64  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |46  | | |  | |  | | | .
   . | |  | | |  | |  | | |  55|  | | |  | |  | | | .
   . | |  | | |  | |  | | |  |8|  | | |  | |  | | | .
   . | |  | | |  | |  | | |  6 |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  6 |  | | |  | |  | | | .
   . | |  | | |  | |  | | |  55|  | | |  | |  | | | .
 5
   . | |  | | |  | |  | | |  8 |  | | |  | |  | | | .
   . | |  | | |  | |  | | |8 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |7|  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |64  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | 46|  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |6|  | |  | | |  | |  | | | .
 6
   . | |  | | |  | |  | 555  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | | 6| | |  | |  | | 46 | |  | | |  | |  | | | .
   . | | 6| | |  | |  | | |8 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | 4  | | |  | |  | | |55| |  | | |  | |  | | | .
 7
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | |  | | |  | |  | | | 8| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |4 56| |  | |  |4| 6  | |  | | |  | |  | | | .
   . | |  | | |  | |  |5| 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
 8
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |6|  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |46  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
 9
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   .4|45  | | | 66 |  54| 8 45 |  | | |  | |  | | | .
   .5|45  | | | 65 4  |6| | 55 |  | | |  | |  | | | .
   . |64  | | | 4| 5  45| |  | |  | | |  | |  | | | .
   . |64  | | |  | |  |4| |  | |  | | |  | |  | | | .
   . |55  | | |  | |  |5| |  | |  | | |  | |  | | | .
   . |55  | |4|  | |  44| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  |8| |  | |  | | |  | |  | | | .
 10
   . | |  | | |  | |  |8| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  46| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  55| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  46| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  |7| |  | |  | | |  | |  | | | .
   . | |  | | |  | | 464| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |7|  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
 11
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
   . | |  | | |  | |  | | |46| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |64| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | |  | | |  | |  | | | 8| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |7 | |  | | |  | |  | | | .
 12
   . | |  | | |  | |  | | | 7| |  | | |  | |  | | | .
   . | |  | | |  | |  | | | 6| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |55| |  | | |  | |  | | | .
   . | |  | | |  | |  | | |64| |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |46  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
 13
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |46  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
 14
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |46  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 7  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
   . | |  | | |  | |  | | 6  | |  | | |  | |  | | | .
   . | |  | | |  | |  | |55  | |  | | |  | |  | | | .
 15
   . | |  | | |  | |  | | 8  | |  | | |  | |  | | | .
   .5| |  5554|4 | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  |6|  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | 64 | | |  | |  | | |  | |  | | | .
   . | |  | | |  | 7  | | |  | |  | | |  | |  | | | .
   . | |  | | |  |55  | | |  | |  | | |  | |  | | | .
   .7|64  | |4444455  | | |  | |  | | |  | |  | | | .
   .55 4  | | |  | |  | | |  | |  | | |  | |  | | | .
 16
   . | |  | | |  | |  | | |  | |  | | |  | |  | | | .
   . | |  | | |  55|  | | |  | |  | | |  | |  | | | .
   . | |  | | |  | 46 | | |  | |  | | |  | |  | | | .
   . | |  | | |  |8| 5| | |  | |  | | |  | |  | | | .
   . | |  | | |  |8| 5| | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  8 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  7 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  7 | |  | |  | | |  | |  | | | .
 17
   . | |  | | |  |5|  64| |  | |  | | |  | |  | | | .
   . | |  | | |  |4|  7 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  6 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  64| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  6 | |  | |  | | |  | |  | | | .
   . | |  | | |  | | 46 | |  | |  | | |  | |  | | | .
   . | | 5| | |  | |  7 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  55| |  | |  | | |  | |  | | | .
 18
   . | |  | | |  | |  6 | |  | |  | | |  | |  | | | .
   . | |  | | |  | |  55| |  | |  | | |  | |  | | | .
   . | |  | | |  | |  8 | |  | |  | | |  | |  | | | .
   . 57|  | | 6  |8| 88 4 |  | |  | | |  | |  | | | .


Рецензии