Files
hamori/docs/chord_format_spec.md
T
H1K0 967257a555 docs: add chord format specification
Authoritative .chord file format spec covering header fields, body
syntax, chord symbol grammar, tokenization rules, and key normalization.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 10:40:39 +03:00

19 KiB
Raw Blame History

Спецификация формата данных

Проект: генератор аккордовых последовательностей

Версия: 1.0 Дата: 2026-05-03


1. Архитектура формата

Формат двухуровневый:

  • Источник — то, что ты пишешь руками. Близок к лид-шиту, человекочитаем, легко правится.
  • Токены — то, что видит модель. Факторизованное представление с маленьким словарём.

Между уровнями стоит парсер. Источник → токены — детерминированное преобразование.


2. Исходный формат

2.1 Структура файла

Один файл — одна пьеса. Расширение .chord. Кодировка UTF-8.

# title: Sea Glass
# key: D_major
# time: 4/4
# subdivision: 4
# style: user
# tempo_bucket: medium

[intro]
| D     . . . | A/C#  . . . | Bm7  . . . | A     . . . |

[verse]
| D     . . . | F#m7  . . . | G     . . . | A     . . . |
| Bm7   . . . | F#m7  . . . | G     . . . | Asus4 . A . |

[chorus]
| Gmaj7 . . . | A     . . . | F#m7  . . . | Bm7   . . . |
| Gmaj7 . . . | A     . . . | D     . . . | D     . . . |

2.2 Шапка (метаданные)

Любая строка, начинающаяся с #, — метаданные. Формат: # key: value.

Поле Обязательно Допустимые значения Пример
title да свободная строка Sea Glass
key да <note>_major или <note>_minor, где <note>C, C#, D, D#, E, F, F#, G, G#, A, A#, B D_major
time да 4/4, 3/4, 6/8, 2/4, 12/8 4/4
subdivision да 4 (четвертные) или 8 (восьмые) 4
style да user, jpop, classical, jazz, other user
tempo_bucket нет slow, medium, fast, very_fast medium

subdivision определяет, сколько позиций в одном такте. В 4/4 при subdivision: 4 — 4 позиции на такт; при subdivision: 8 — 8 позиций.

2.3 Структурные теги секций

В квадратных скобках на отдельной строке. Действуют до следующего тега.

Тег Назначение
[intro] вступление
[verse] куплет
[prechorus] предприпев
[chorus] припев
[bridge] бридж
[interlude] проигрыш
[solo] соло
[outro] концовка

2.4 Записи аккордов

Внутри секции — последовательность тактов. Каждый такт обрамлён |.

Внутри такта — subdivision позиций, разделённых пробелами. На каждой позиции либо аккордовый символ (новый аккорд начинается здесь), либо . (удержать предыдущий аккорд), либо NC (no chord — пауза/тишина в гармонии).

| D . . . | A/C# . . . |    ← такт 1: D на 4 четверти; такт 2: A/C# на 4 четверти
| Em7 . D . | A . . . |     ← такт 3: Em7 на 2 четверти, D на 2 четверти
| NC . . . | D . . . |      ← такт 4: пауза; такт 5: D

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

2.5 Комментарии

Строки, начинающиеся с //, парсер игнорирует. Можно использовать для пометок.

// здесь модулируем в параллельный минор
[bridge]
| Bm . . . | F#m . . . |

3. Аккордовая нотация

3.1 Корневой тон

Один из 12 классов высоты, через диез: C, C#, D, D#, E, F, F#, G, G#, A, A#, B.

Бемольная запись (Db, Eb, Gb, Ab, Bb) допускается на входе и парсер сам приведёт к диезной форме. Энгармоническое написание для модели не значимо.

3.2 Базовые качества (18)

Символ Название Состав от корня
maj или ничего мажорное трезвучие 1, 3, 5
m или min минорное трезвучие 1, b3, 5
dim или ° уменьшённое трезвучие 1, b3, b5
aug или + увеличенное трезвучие 1, 3, #5
sus2 sus2 1, 2, 5
sus4 sus4 1, 4, 5
maj7 или M7 большой мажорный септаккорд 1, 3, 5, 7
m7 минорный септаккорд 1, b3, 5, b7
7 доминантовый септаккорд 1, 3, 5, b7
m7b5 или ø полууменьшённый 1, b3, b5, b7
dim7 или °7 уменьшённый септ 1, b3, b5, bb7
mM7 или m(maj7) минорно-мажорный септ 1, b3, 5, 7
7sus4 доминанта на сус4 1, 4, 5, b7
aug7 или 7#5 увеличенный септ 1, 3, #5, b7
6 мажорный с секстой 1, 3, 5, 6
m6 минорный с секстой 1, b3, 5, 6
add9 мажор с добавленной ноной 1, 3, 5, 9
m(add9) минор с добавленной ноной 1, b3, 5, 9

Запись «без качества» (просто C) автоматически = Cmaj.

3.3 Расширения (опционально)

Один опциональный слот после качества. Поддерживаются:

Символ Значение
9, b9, #9 нона (натуральная, пониженная, повышенная)
11, #11 ундецима
13, b13 терцдецима

Примеры:

  • Cmaj9 = Cmaj7 + расширение 9
  • C7b9 = C7 + расширение b9
  • Fmaj7#11 = Fmaj7 + расширение #11 (лидийский)
  • Dm9 = Dm7 + расширение 9

Условные сокращения, которые парсер расшифровывает:

  • 9 (например, C9) = 7 + расширение 9 (доминантовая нона)
  • maj9 = maj7 + расширение 9
  • m9 = m7 + расширение 9
  • 13 = 7 + расширение 13
  • m11 = m7 + расширение 11

Если хочется указать сразу несколько расширений (например, альтерированный доминант C7#9b13) — модель использует только первое расширение в записи. Это сознательное упрощение, чтобы не раздувать комбинаторику. На практике для J-Pop и поп-музыки этого хватает; для джазовых случаев можно записать как ближайший эквивалент.

3.4 Бас и слэш-аккорды

Для инверсий и слэш-аккордов — стандартный формат <chord>/<bass>:

F/A     ← F с басом A (первое обращение)
G/B     ← G с басом B
F/G     ← F с басом G (характерный «on-аккорд» из J-Pop)
Em7/G   ← Em7 с басом G

Бас может быть как любой из 12 нот, так и любой ступенью аккорда. Парсер не проверяет, входит ли бас в состав аккорда — это ответственность транскрибера.

Если слэш-нотация не указана, считается, что бас совпадает с корнем (BASS = root).

3.5 Специальные значения

Запись Значение
. удержать предыдущий аккорд на этой позиции
NC нет аккорда (пауза в гармонии)
? unknown — для случаев, когда не уверен в транскрипции; парсер заменит на <UNK>

4. Внутреннее токенизированное представление

4.1 Словарь (≈100 токенов)

Служебные (4): <BOS>, <EOS>, <PAD>, <UNK>

Метаданные (всегда в начале последовательности, после <BOS>):

  • KEY_<note>_<mode> — 24 токена (12 нот × major/minor)
  • TIME_<n>/<m> — 5 токенов: TIME_4/4, TIME_3/4, TIME_6/8, TIME_2/4, TIME_12/8
  • STYLE_<x> — 5 токенов: STYLE_user, STYLE_jpop, STYLE_classical, STYLE_jazz, STYLE_other
  • TEMPO_<x> — 4 токена: TEMPO_slow, TEMPO_medium, TEMPO_fast, TEMPO_very_fast
  • SUB_<n> — 2 токена: SUB_4, SUB_8

Структурные:

  • SEC_<x> — 8 токенов: SEC_intro, SEC_verse, SEC_prechorus, SEC_chorus, SEC_bridge, SEC_interlude, SEC_solo, SEC_outro
  • BAR — конец такта

Аккордовые (4 слота на каждый аккорд):

  • ROOT_<note> — 12 токенов
  • QUAL_<x> — 18 токенов (см. §3.2)
  • EXT_<x> — 8 токенов: EXT_none, EXT_9, EXT_b9, EXT_#9, EXT_11, EXT_#11, EXT_13, EXT_b13
  • BASS_<x> — 13 токенов: BASS_root плюс 12 нот

Временные/специальные:

  • HOLD — позиция продолжает предыдущий аккорд
  • NC — пауза в гармонии

Итого: ≈100 токенов.

4.2 Структура последовательности

<BOS>
KEY_<x>  TIME_<x>  SUB_<x>  STYLE_<x>  [TEMPO_<x>]
SEC_<x>
ROOT_<x>  QUAL_<x>  EXT_<x>  BASS_<x>   ← новый аккорд = ровно 4 токена
HOLD                                     ← удержание = 1 токен
HOLD
HOLD
BAR
ROOT_<x>  QUAL_<x>  EXT_<x>  BASS_<x>
HOLD
ROOT_<x>  QUAL_<x>  EXT_<x>  BASS_<x>
HOLD
BAR
SEC_<x>
...
<EOS>

4.3 Правила токенизации (источник → токены)

  1. Прочитать шапку → выпустить <BOS> и токены метаданных.
  2. Каждая [section] строка → SEC_<x>.
  3. Для каждой позиции внутри такта:
    • Если аккорд: разобрать на (root, quality, extension, bass). Выпустить 4 токена в этом порядке.
    • Если .: выпустить HOLD.
    • Если NC: выпустить NC.
    • Если ?: выпустить <UNK>.
  4. После последней позиции такта → BAR.
  5. В конце пьесы → <EOS>.

4.4 Инвариант длины

При subdivision: 4 каждый такт даёт переменное число токенов (от 5 до 17): один BAR + от 4 (один аккорд × 4 поля) до 16 (четыре аккорда × 4 поля), плюс HOLD-ы. В среднем для поп-музыки получится 6–10 токенов на такт.

Типичная пьеса (~80 тактов) → 600800 токенов. Это комфортно укладывается в стандартное контекстное окно 1024–2048.


5. Полный пример

5.1 Источник

# title: Example Song
# key: C_major
# time: 4/4
# subdivision: 4
# style: user
# tempo_bucket: medium

[verse]
| Cmaj7 . . . | Am7 . . . | Dm7 . G7 . | Cmaj7 . . . |

[chorus]
| F . . . | F/G . G . | Em7 . Am7 . | Dm7 . G7sus4 G7 |

5.2 Токенизация

<BOS>  KEY_C_major  TIME_4/4  SUB_4  STYLE_user  TEMPO_medium

SEC_verse

ROOT_C  QUAL_maj7  EXT_none  BASS_root
HOLD  HOLD  HOLD
BAR

ROOT_A  QUAL_min7  EXT_none  BASS_root
HOLD  HOLD  HOLD
BAR

ROOT_D  QUAL_min7  EXT_none  BASS_root
HOLD
ROOT_G  QUAL_7  EXT_none  BASS_root
HOLD
BAR

ROOT_C  QUAL_maj7  EXT_none  BASS_root
HOLD  HOLD  HOLD
BAR

SEC_chorus

ROOT_F  QUAL_maj  EXT_none  BASS_root
HOLD  HOLD  HOLD
BAR

ROOT_F  QUAL_maj  EXT_none  BASS_G
HOLD
ROOT_G  QUAL_maj  EXT_none  BASS_root
HOLD
BAR

ROOT_E  QUAL_min7  EXT_none  BASS_root
HOLD
ROOT_A  QUAL_min7  EXT_none  BASS_root
HOLD
BAR

ROOT_D  QUAL_min7  EXT_none  BASS_root
HOLD
ROOT_G  QUAL_7sus4  EXT_none  BASS_root
ROOT_G  QUAL_7  EXT_none  BASS_root
BAR

<EOS>

(В реальности — без переносов строк и пустых строк, всё идёт одним потоком; здесь форматирование только для читаемости.)


6. Краевые случаи и соглашения

6.1 Анакруза (затакт)

Записывается как первый «обычный» такт, но с NC на пустых позициях:

| NC . . D | G . . . |

6.2 Смена тональности

Если внутри пьесы происходит модуляция, можно ввести inline-тег [modulate: F_major]. На уровне токенов это выпустит KEY_F_major посреди последовательности. Для первой версии этим лучше не пользоваться — модель проще учить на тонально стабильных пьесах. Если в твоих работах часто бывают модуляции, расскажи отдельно — обсудим, как разрезать пьесу на тонально-однородные сегменты.

6.3 Смена тактового размера

Аналогично — inline [time: 3/4]. Тоже лучше избегать в первой версии.

6.4 Полиаккорды

Запись D/C (треугольник вверху, квадрат внизу) не поддерживается как полиаккорд, только как inverse/слэш. В подавляющем большинстве случаев в поп-музыке слэш-нотации достаточно. Истинные полиаккорды редки и для проекта не критичны.

6.5 Аккорды вне 12-ступенной системы

Не поддерживаются. Если в материале есть микротональные элементы — округлять до ближайшего темперированного аккорда или отмечать как ?.

6.6 Pickup notes / fills

Гармонические заполнения и проходящие аккорды записываются обычным образом, на сетке. Если они короче subdivision (например, проходящий восьмой аккорд при subdivision: 4) — либо переключить subdivision на 8 для этой пьесы, либо округлить.

6.7 Имена файлов

Рекомендованный формат: YYYY_NN_short-title.chord, где YYYY — год создания пьесы, NN — её номер в этом году. Это упростит хронологическую сортировку датасета и поможет, если потом захочется анализировать эволюцию стиля во времени.

6.8 Что НЕ кодируется

Сознательно вне формата:

  • voicing (расположение голосов внутри аккорда сверх баса);
  • ритмический паттерн внутри удержания (пунктир, синкопы внутри одного аккорда);
  • динамика, артикуляция;
  • тембр, аранжировка;
  • мелодия (это отдельная задача).

Это правильный уровень абстракции для гармонической задачи. Всё остальное — на ручную работу в DAW при использовании сгенерированной прогрессии.


7. Чек-лист транскрипции

При перекладывании пьесы из DAW в .chord-файл:

  1. Заполнить шапку: title, key, time, subdivision, style, tempo_bucket.
  2. Прослушать пьесу целиком, разметить секции.
  3. Для каждой секции — определить шаблонную единицу (4 такта? 8?), записать гармонию по позициям.
  4. Прогнать парсер (когда он будет написан) и проверить, что нет <UNK> токенов и предупреждений о неизвестных качествах.
  5. Сравнить «на слух»: воспроизвести аккорды в DAW по транскрипции и убедиться, что слышимая гармония совпадает с оригиналом.

Этот шаг 5 особенно важен — даже с абсолютным слухом легко пропустить инверсию или septима↔nona в плотной фактуре.


8. История изменений

  • v1.0 — первоначальная спецификация.