Как Tomodachi Voice Lab синтезирует 8-битные голоса

12 мин чтения
Tomodachi LifeWeb Audio APIСинтез голосаРуководства

Tomodachi Voice Lab строит свои 8-битные голоса Mii на графе Web Audio API из трёх узлов: один OscillatorNode генерирует тон, один BiquadFilterNode смягчает его, а один GainNode формирует его огибающую громкости. Это руководство препарирует этот конвейер в точности так, как он работает в Tomodachi Voice Lab — каждую константу, каждый пресет и каждое решение по планированию — чтобы вы могли понять, воспроизвести или расширить эстетику бип-речи, вызывающую ассоциации с Tomodachi Life: Living the Dream. Каждое число ниже процитировано из исходного кода сайта, и если значение является оценкой сообщества, а не тем, что задокументировала Nintendo, в тексте это указано.

Почему голоса Tomodachi говорят бипами

Фирменная особенность аудио Tomodachi Life — бип-речь: вместо записанных диалогов каждый Mii вокализирует короткими синтезированными тонами, которые следуют ритму фразы, но никогда не образуют настоящих слов. Этот подход восходит к портативным истокам серии, где размер картриджа и звуковое оборудование делали полное озвучивание непрактичным, и он дожил до Tomodachi Life: Living the Dream на Switch, потому что бипы стали частью идентичности серии. Результат воспринимается как речь, потому что копирует просодию речи — движение высоты тона, тайминг слогов, паузы — оставаясь при этом намеренно нелексической.

Nintendo никогда не публиковала фактический метод синтеза игры, поэтому любая браузерная реконструкция по определению является оценкой сообщества. Лаборатория стремится к эстетике, а не к побитово точному воспроизведению, и основную работу делают три свойства. Во-первых, тоны короткие: огибающие открываются и закрываются за десятки миллисекунд, поэтому каждый слог начинается и заканчивается чисто. Во-вторых, форма волны богата гармониками: жужжащий тембр считывается как «chiptune» гораздо легче, чем чистый тон. В-третьих, высота тона никогда не статична: небольшие смещения частоты на слог имитируют контур естественной речи. Остальная часть этого руководства показывает, как каждое из этих свойств отображается на конкретный механизм Web Audio API.

Конвейер синтеза, узел за узлом

Каждый звук, который производит лаборатория, проходит ровно через три узла обработки между осциллятором и вашими динамиками. Новый AudioContext создаётся на каждое воспроизведение — лаборатория никогда не держит глобальный аудиограф живым — и каждый слог планирует внутри него собственный набор узлов:

OscillatorNode ──▶ BiquadFilterNode (lowpass) ──▶ GainNode ──▶ AudioContext.destination

                        только для пресета Пожилой:
  LFO OscillatorNode (5 Hz) ──▶ GainNode (depth 15) ──▶ main osc.frequency

OscillatorNode — источник звука. Его type берётся из выбранного пресета (sawtooth для четырёх из пяти пресетов, square для робота), а его frequency задаётся ползунком высоты тона. Поскольку осциллятор — это чистый генератор формы волны, у него нет собственных тембровых регуляторов — всё, что делает звучание одного пресета отличным от другого, представляет собой планирование параметров дальше по цепочке.

BiquadFilterNode всегда настроен как фильтр lowpass, его частота среза берётся из значения filterFreq пресета (900 – 2500 Hz в зависимости от пресета). Фильтр нижних частот ослабляет гармоники выше среза — именно это превращает жужжание сырой пилообразной волны на полную мощность во что-то близкое к голосу: более тёмные пресеты (Пожилой на 900 Hz) сохраняют только низкие гармоники, а более яркие пресеты (Ребёнок на 2500 Hz) пропускают искристость, из-за которой голос звучит маленьким и юным.

GainNode — место, где живёт огибающая, планируемая по четырём точкам автоматизации. Усиление начинается с 0 в момент начала слога, линейно нарастает до целевого значения пресета (0.2 – 0.3) за время атаки, удерживается на этом значении, пока до конца не останется одно время спада, а затем линейно возвращается к 0. Вызовы — setValueAtTime() для опорных точек и linearRampToValueAtTime() для рамп — простая огибающая атака/удержание/спад без экспоненциальных кривых, что сохраняет характерную резкость звука, соответствующую 8-битной стилистике.

Существует необязательная четвёртая пара узлов: вибрато. Когда пресет его включает, второй OscillatorNode, работающий как LFO (генератор низкой частоты), функционирует на vibratoRate пресета и питает GainNode, установленный на vibratoDepth, который подключён к параметру frequency основного осциллятора. Это классическая частотная модуляция — в пресете Пожилой LFO на 5 Hz колеблет высоту тона на ±15 Hz, создавая дрожащее качество, связанное с возрастными голосами. Только пресет Пожилой его включает; остальные четыре полностью оставляют вибрато отключённым.

Как звучит каждая форма волны (и когда её выбирать)

Выбор формы волны — самое важное тембровое решение во всём конвейере, потому что оно определяет гармонический состав, который затем формируют фильтр и огибающая. OscillatorNode из Web Audio API предлагает четыре стандартных типа, и каждый обладает собственным характером:

Форма волныГармонический составХарактерИспользуется пресетами
sineТолько основной тонЧистый, похожий на флейту, без жужжанияНет (доступно через OscillatorType)
squareНечётные гармоники, сильныеПолый, классический сольный канал NESРобот
sawtoothВсе гармоники, затухающиеЖужжащий, язычковый, ближе всего к вокальному богатствуВзрослый мужчина, Взрослая женщина, Пожилой, Ребёнок
triangleМало нечётных гармоник, слабыеМягкий, мелодичный, слегка приглушённыйНет (доступно через OscillatorType)

Пресеты лаборатории используют только два из четырёх: sawtooth несёт четыре органических голоса, а square — робота. Это разделение намеренное. Пилообразная волна содержит энергию на каждой гармонике, что после фильтрации нижних частот оставляет плотное, похожее на голос ядро — причина, по которой она приближает спетые или произнесённые тоны лучше, чем любая другая базовая форма волны. Прямоугольная волна (меандр) сохраняет только нечётные гармоники с большей энергией вверху, что даёт полое, носовое, безошибочно электронное качество, которого хочет пресет Робот. Sine и triangle не используются ни одним текущим пресетом, но остаются изменениями в одну строку через то же поле OscillatorType: синусоида подходит для чистых звуковых эффектов вроде колокольчиков, а треугольная волна — для мягких фоновых блипов, где пилообразная была бы слишком агрессивной.

Разбор пяти пресетов голоса

Пять пресетов — это пять наборов параметров поверх одного и того же графа из трёх узлов, и их различия полностью перечислимы. Вот полная таблица, процитированная напрямую из константы VOICE_PRESETS в исходном коде:

ПресетФорма волныБазовая частотаСрез ФНЧУсилениеВибратоАтакаСпад
Взрослый мужчинаsawtooth180 Hz1200 Hz0.30Выкл0.02 s0.05 s
Взрослая женщинаsawtooth350 Hz1800 Hz0.25Выкл0.02 s0.04 s
Пожилойsawtooth120 Hz900 Hz0.305 Hz, ±15 Hz0.04 s0.08 s
Ребёнокsawtooth600 Hz2500 Hz0.20Выкл0.01 s0.03 s
Роботsquare250 Hz1500 Hz0.25Выкл0 s0 s

Взрослый мужчина заякоривает набор на базовой частоте 180 Hz, находящейся в нижней части типичного диапазона речи взрослого мужчины, с фильтром нижних частот на 1200 Hz, который укрощает жужжание пилообразной волны до чего-то округлого. Взрослая женщина почти удваивает базу до 350 Hz, открывает фильтр до 1800 Hz для более яркого тона и урезает и усиление (0.25), и спад (0.04 s) для чуть более чёткой артикуляции.

Пожилой — наиболее глубоко обработанный пресет: самый низкий регистр (120 Hz), самый тёмный фильтр (900 Hz), единственное вибрато (LFO 5 Hz с глубиной ±15 Hz) и самая медленная огибающая (0.04 s атака, 0.08 s спад). Последние два значения важны не меньше высоты тона — вялая атака смягчает начало каждого слога, а длинный спад позволяет тонам слегка перетекать в следующий, вызывая менее точную артикуляцию, к которой пресет стремится.

Ребёнок инвертирует почти каждое решение пресета Пожилой: самая высокая база (600 Hz), самый яркий фильтр (2500 Hz), самое низкое усиление (0.20) и самая быстрая огибающая (0.01 s атака, 0.03 s спад). Быстрые огибающие на высоких тонах — классический рецепт озвучивания маленьких существ — каждый слог приземляется как быстрый чирик. Робот — исключение по двум осям: это единственная волна square и единственный пресет с нулевой атакой и нулевым спадом, то есть усиление включается и выключается мгновенно. Эти резкие края дают жёсткое, гейтированное, механическое качество, которого хочет пресет — нет рампы, значит нет мягкости, по построению.

Как высота тона и скорость на самом деле управляют осциллятором

Два ползунка управляют графом в реальном времени: высота тона в диапазоне 100 – 800 Hz со значением по умолчанию 300 Hz и скорость в диапазоне 0.5x – 2.0x со значением по умолчанию 1.0x. Каждый пресет также объявляет свой канонический baseFreq (опорный центр, указанный в таблице выше), который документирует, где этот тип голоса задуман находиться.

Высота тона задаёт частоту осциллятора напрямую, с одной защитой: в пресете Ребёнок воспроизводимая частота равна Math.max(pitch, 500), поэтому перетаскивание ползунка ниже 500 Hz в режиме ребёнка ничего не делает — осциллятор никогда не опускается ниже этой границы. Этот ограничитель защищает характер пресета: детский голос на 150 Hz просто считывался бы как тихий взрослый мужчина.

Скорость управляет временем, а не частотой. Одно нажатие кнопки воспроизведения производит один бип длительностью 0.5 / speed секунд — 1.0 s при 0.5x, 0.5 s при 1.0x и 0.25 s при 2.0x. Тот же делитель применяется к каждой временной константе в текстовом режиме, поэтому голос на 2.0x действительно вдвое быстрее от начала до конца, а не ресемплирован, что сдвинуло бы его высоту. После воспроизведения интерфейс сбрасывает состояние воспроизведения через 500 / speed + 50 миллисекунд — длительность бипа плюс запас в 50 ms.

Из текста в речь, один бип на символ

Режим озвучивания текста в лаборатории — не речевой движок — это тот же конвейер осциллятора из трёх узлов, планируемый по одному разу на символ. Когда вы вводите до 100 символов и нажимаете «говорить», ввод разбивается на отдельные символы, и каждый не-пробельный символ становится одним запланированным слоговым бипом со смещением высоты тона, производным от его кода символа. Временные константы, все разделённые на скорость:

Вариация высоты тона — самая хитрая часть. Смещение частоты каждого символа вычисляется как ((charCode % 20) - 10) × 3, что даёт детерминированный разброс между -30 Hz и +27 Hz вокруг базовой высоты тона. Детерминированность важна: одно и то же слово всегда даёт одну и ту же мелодическую линию, поэтому конкретная фраза становится узнаваемой так же, как узнаваем голос Mii. Поскольку смещения происходят из кодов символов, а не из фонетики, вывод близко следует ритму текста, оставаясь нелексической тарабарщиной — что и есть именно тот эффект бип-речи, который лаборатория приближает.

Проектирование голоса для каждой группы личности

Убедительный голос личности — это в основном решение о диапазоне высоты тона: выберите пресет, который справочная таблица сайта назначает группе личности вашего Mii, а затем установите ползунок высоты тона внутри рекомендованного диапазона. Полное соответствие, используемое справочной таблицей голосовой лаборатории:

Группа личностиПример типаMBTIРекомендуемый пресетДиапазон высоты тона
ОбщительныйЛидерESTJВзрослый мужчина180 – 250 Hz
УверенныйДизайнерINTJВзрослый мужчина150 – 200 Hz
НезависимыйХудожникINFPВзрослая женщина280 – 380 Hz
СпокойныйМечтательINFJПожилой120 – 180 Hz
Детские персонажиЛюбойЛюбойРебёнок500 – 700 Hz
Роботы/ИИ-персонажиЛюбойЛюбойРобот200 – 300 Hz

Обратите внимание, что таблица отображает группы, а не все 16 личностей — четыре группы личности из нашего сопоставления MBTI получают по одному представительному голосовому силуэту, а отдельные личности выражаются тем, где внутри диапазона вы ставите ползунок и с какой скоростью управляете регулятором скорости. Пошаговый рецепт:

  1. 1Выберите пресет по группе. Общительные и Уверенные Mii берут Взрослого мужчину; Независимые Mii — Взрослую женщину; Спокойные Mii — Пожилого, чьё вибрато 5 Hz добавляет расслабленное, неторопливое качество, которым известна группа. Группа Mii определяется его четырьмя ползунками личности — см. таблицу личностей, если она вам ещё неизвестна.
  2. 2Установите ползунок высоты тона внутри диапазона группы. Для Уверенного Дизайнера это означает 150 – 200 Hz; смещение к 150 Hz читается как более внушительное, к 200 Hz — как более энергичное. Нижняя граница 500 Hz пресета Ребёнок означает, что диапазон 500 – 700 Hz соблюдается сам собой.
  3. 3Выберите скорость под стиль речи. Быстрые в речи типы Артистов оправдывают 1.4x – 2.0x; сонный Мечтатель естественно располагается на 0.5x – 0.8x. Скорость меняет только длительность, поэтому она никогда не расстраивает голос, выбранный на шаге 2.
  4. 4Протестируйте короткой фразой. Введите 20 – 30 символов в текстовое поле и прислушайтесь к паузе во фразе после каждого 5-го символа — если каденция ощущается неподходящей для личности, отрегулируйте скорость, прежде чем трогать высоту тона.
  5. 5Итерируйте по своей истории. Каждое воспроизведение — пресет, высота тона, скорость и до 100 символов текста — сохраняется в локальную панель истории IndexedDB внутри инструмента, поэтому вы можете сравнить две настройки в духе A/B, ничего не записывая. Ничего не покидает браузер.

Строки ребёнка и робота намеренно находятся вне системы личностей: любой Mii можно озвучить любым из них, поэтому их столбец MBTI гласит «Любой». Огибающая нулевой длины робота делает его терпимым к темпу — на любой скорости он сохраняет одну и ту же гейтированную жёсткость, поэтому это единственный голос, где скорость является чисто комедийным регулятором.

Почему нет запасного варианта на Web Speech API

Лаборатория намеренно избегает Web Speech API браузера — в её кодовой базе нет ни одного вызова speechSynthesis, а режим озвучивания текста — чистое планирование осциллятора. Это проектное решение с защитимой аргументацией и реальным компромиссом, и стоит разобрать и то и другое.

Аргументация: speechSynthesis производит естественные человеческие голоса — именно того, чего 8-битная голосовая лаборатория не хочет. Он также делегирует выбор голоса операционной системе, поэтому один и тот же текст может звучать по-разному в разных браузерах и на разных устройствах, а некоторые браузеры загружают голосы лениво, с заметной задержкой первой фразы. Подход «один бип на символ» держит каждый звук внутри того же графа из трёх узлов, который использует режим одиночного бипа, гарантирует одинаковый тембр везде, где работает Web Audio API, и стартует мгновенно, потому что ничего не нужно загружать.

Компромисс: вывод не является разборчивой речью. Он следует ритму и контуру текста, но не производит узнаваемых слов, поэтому вызывает каденцию бип-речи Tomodachi Life, а не её разборчивость — впрочем, тарабарщина игры тоже не разборчива, что, можно сказать, и есть суть. Остановка воспроизведения столь же прямолинейна и эффективна: лаборатория закрывает весь AudioContext через close(), что немедленно убивает каждый запланированный узел, а не делает плавное затухание.

Ограничения, заявленные честно

Три ограничения очерчивают, что этот синтезатор может честно заявлять. Во-первых, он приближает эстетику, а не движок игры: Nintendo никогда не документировала, как Tomodachi Life генерирует свои голоса, поэтому значения пресетов здесь — оценки сообщества, настроенные на вызов звука серии, а не извлечённые константы. Голоса напоминают игровые, но не являются их репликами.

Во-вторых, синтез монофоничен и не содержит формант. Каждый слог — один осциллятор, сформированный одним фильтром нижних частот, тогда как естественная речь — и, предположительно, более сложный движок игры — несёт формантную структуру голосового тракта. Поэтому вывод считывается как chiptune-озвучивание, а не сэмплированная речь, и этот разрыв больше всего заслуживает изучения, если вы расширяете код: второй осциллятор на октаву выше или фильтр с запланированным движением частоты — оба подтолкнули бы результат ближе к вокальной территории.

В-третьих, всё зависит от поддержки браузером. Используемая здесь Web Audio API — AudioContext, OscillatorNode, BiquadFilterNode, GainNode — поддерживается во всех текущих основных браузерах, но характер вывода Web Audio API всё же слегка различается между аудиостеками устройств, а браузеры, блокирующие автовоспроизведение до действия пользователя, потребуют нажатия кнопки воспроизведения, которую лаборатория уже предоставляет. В плане приватности инструмент полностью клиентский: синтез выполняется в браузере, и единственное хранилище — локальная история IndexedDB — ни аудио, ни текст никуда не загружаются.

Попробуйте конвейер сами

Быстрее всего усвоить модель — подвигать два ползунка и услышать, как граф отвечает в реальном времени:

27 сентября 2026 г.

Как 16 личностей Tomodachi Life соотносятся с MBTI

Читать
27 сентября 2026 г.

Как найти любимое блюдо каждого Mii: метод тестирования

Читать