# Спецификация формата данных ## Проект: генератор аккордовых последовательностей **Версия:** 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` | да | `_major` или `_minor`, где `` — `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 Бас и слэш-аккорды Для инверсий и слэш-аккордов — стандартный формат `/`: ``` 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 — для случаев, когда не уверен в транскрипции; парсер заменит на `` | --- ## 4. Внутреннее токенизированное представление ### 4.1 Словарь (≈100 токенов) **Служебные (4):** ``, ``, ``, `` **Метаданные (всегда в начале последовательности, после ``):** - `KEY__` — 24 токена (12 нот × major/minor) - `TIME_/` — 5 токенов: `TIME_4/4`, `TIME_3/4`, `TIME_6/8`, `TIME_2/4`, `TIME_12/8` - `STYLE_` — 5 токенов: `STYLE_user`, `STYLE_jpop`, `STYLE_classical`, `STYLE_jazz`, `STYLE_other` - `TEMPO_` — 4 токена: `TEMPO_slow`, `TEMPO_medium`, `TEMPO_fast`, `TEMPO_very_fast` - `SUB_` — 2 токена: `SUB_4`, `SUB_8` **Структурные:** - `SEC_` — 8 токенов: `SEC_intro`, `SEC_verse`, `SEC_prechorus`, `SEC_chorus`, `SEC_bridge`, `SEC_interlude`, `SEC_solo`, `SEC_outro` - `BAR` — конец такта **Аккордовые (4 слота на каждый аккорд):** - `ROOT_` — 12 токенов - `QUAL_` — 18 токенов (см. §3.2) - `EXT_` — 8 токенов: `EXT_none`, `EXT_9`, `EXT_b9`, `EXT_#9`, `EXT_11`, `EXT_#11`, `EXT_13`, `EXT_b13` - `BASS_` — 13 токенов: `BASS_root` плюс 12 нот **Временные/специальные:** - `HOLD` — позиция продолжает предыдущий аккорд - `NC` — пауза в гармонии **Итого: ≈100 токенов.** ### 4.2 Структура последовательности ``` KEY_ TIME_ SUB_ STYLE_ [TEMPO_] SEC_ ROOT_ QUAL_ EXT_ BASS_ ← новый аккорд = ровно 4 токена HOLD ← удержание = 1 токен HOLD HOLD BAR ROOT_ QUAL_ EXT_ BASS_ HOLD ROOT_ QUAL_ EXT_ BASS_ HOLD BAR SEC_ ... ``` ### 4.3 Правила токенизации (источник → токены) 1. Прочитать шапку → выпустить `` и токены метаданных. 2. Каждая `[section]` строка → `SEC_`. 3. Для каждой позиции внутри такта: - Если аккорд: разобрать на (root, quality, extension, bass). Выпустить 4 токена в этом порядке. - Если `.`: выпустить `HOLD`. - Если `NC`: выпустить `NC`. - Если `?`: выпустить ``. 4. После последней позиции такта → `BAR`. 5. В конце пьесы → ``. ### 4.4 Инвариант длины При `subdivision: 4` каждый такт даёт **переменное** число токенов (от 5 до 17): один `BAR` + от 4 (один аккорд × 4 поля) до 16 (четыре аккорда × 4 поля), плюс `HOLD`-ы. В среднем для поп-музыки получится 6–10 токенов на такт. Типичная пьеса (~80 тактов) → **600–800 токенов**. Это комфортно укладывается в стандартное контекстное окно 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 Токенизация ``` 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 ``` (В реальности — без переносов строк и пустых строк, всё идёт одним потоком; здесь форматирование только для читаемости.) --- ## 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. Прогнать парсер (когда он будет написан) и проверить, что нет `` токенов и предупреждений о неизвестных качествах. 5. Сравнить «на слух»: воспроизвести аккорды в DAW по транскрипции и убедиться, что слышимая гармония совпадает с оригиналом. Этот шаг 5 особенно важен — даже с абсолютным слухом легко пропустить инверсию или septима↔nona в плотной фактуре. --- ## 8. История изменений - **v1.0** — первоначальная спецификация.