*_orig.wav — и работает от него до мастера. Роман, 03.10.2026: «Петли у нас пишутся на 32 bit float и оч важно править именно исходник и работать с ним, он позволяет больше работы делать». Этап обязательный до сборки: голос чинят и выбирают на слух раньше экранов и рендера. Движки целиком — Фильм кодом, оригиналы и синхрон — Исходники машине, варианты голоса на странице версии — План экранов.TX##_MIC###_*_orig.wav из 99_Pipeline/DJI_Audio/: float 32, 48 кГц, моно. Уровень ставят по речи, не по пику; до лимитера всё держится в float (alimiter level=disabled). Оригинал не перезаписывать — правка живёт копией рядом; где она лежит и как называется, решает Роман (плитка «Решает Роман»).Дорожка «На слух» стоит до сборки: на YTCG37 «голос — эхо» всплыл на готовом фильме и стоил пересборки речи, экранов по звуку и рендера.
TX##_MIC###_ГГГГММДД_ЧЧММСС_orig.wav — float 32, 48 кГц, моно; файл ≈ 30 мин, у спаренных TX вшит таймкод{проект}/99_Pipeline/DJI_Audio/; на карте — папка TX_MIC001_*/01_Source/Audio/; время фильма — по нему…_orig__S08.wav — симлинки на тот же файл; целого они не заменяют_edit.wav — обработан рекордером, на части дублей короче; к картинке не подходит*_timeline.wav — сжатое время секвенции Premiere, паузы выброшены; точность среза ≤ 0,67 с-ac 1 сливает двух людей — L и R часто разные микрофоныПравило записано в dc.py doc_cut («*_timeline.wav сюда не годятся… звук берётся из *_orig*.wav»), на странице съёмочного дня («в разбор и в 01_Source идёт только _orig») и в CLAUDE.md.
alimiter=limit=0.85:level=disabled:attack=1pcm_f32le; alimiter везде level=disabledКопии для распознавания с float-петличек: пик задаёт один удар по капсюлю, речь — нет.
alimiter limit 0,85 · attack 1 · level=disabled — пик не тянется в потолокПять движков — на странице Фильм кодом; здесь только их звук. Числа мастера у всех из 17_audio/standard.py; речь читается из источника теми же сэмплами, что стоят в листе (кадр = 1920 сэмплов).
| Движок | Источник сегодня | Цепочка |
|---|---|---|
| autocut | стемы из прокси AAC; оригинал PCM сменяет его после сверки корреляцией | stems → clean (речь −30 LUFS, изолятор, 4 варианта) → автовыбор наименее обработанного → клип −26 LUFS, компрессор −22 дБ 2,5:1 → тон сада −50 LUFS → Epidemic под речью −20 / −21 дБ → мастер: усиление → alimiter −1,5 → подстройка до −14 ±0,03 |
| headless мультикам | WAV рекордера в 01_Source/Audio/, две петлички | резы только в тишине → обе петлички одними сэмплами, кроссфейд 20 мс (6 в провале) → автомикс Дугана, доля ≥ −15 дБ → сумма −20 LUFS, компрессор −21 дБ 2,5:1 → подложка −21 / заставка −15 дБ RMS к речи → мастер volume → 192k → alimiter → 48k |
| solo | петличка по source.lav задания, синхронна клипу | edges по звуку → clean: isolate: речь −30, запас 2 с, изолятор → 30 Гц → сдвиг ≤ 48; wet 0,9, EQ lav_warm или recipe_c, компрессор −24 дБ 2:1 (или denoise: afftdn, задержка 25 мс снята) → подложка −21 / финал −7 дБ → мастер + снятие задержки лимитера |
| doc_cut | tx_strips_source ингеста — целые _orig | sync measure (окна 10 с через 45 с, MAD ≤ 12 мс) → stems: петличка +20 дБ, __raw + __iso → dialog: wet 0,72 петличка / 0,86 камера, герой −24 / автор −26,5 дБFS, второй источник −16 дБ пока говорит первый → подложка −22 → мастер −14, s24 |
| story_cut | ⚠ звук клипа Transcription/<клип>_AUDIO.wav (0102: s16, −ac 2), не _orig.wav | группа к −20 дБFS RMS, кроссфейд 12 мс, стемы по микрофону lav / car / cam / pub → nat: перебивки −30, укрытия −38 → музыка по энергии 1–4 = −26 / −20 / −11 / −2 дБ, в паузах +7, уход за 0,35 с до слова → мастер |
--wet 0…100 --quality high|standard --pregain --delay-comp --info; high — macOS 15+swiftc -O voice_isolate.swift -o bin/voice_isolate; бинарь вне git_v1_Orig · _v2_Soft · _v3_Clean · _v4_Warm — по порядку, без букв-рецептовsound_ab: пять вариантов куска 24 с на −16 LUFS, m4a → ~/Downloads/<CODE>_sound_choice/ladder: sound / music / edges на −20 LUFS и страница с плеерами и «Скопировать выбор»sound.speech задания (clean, wet, eq, comp) или --variant день=warm; менять одной строкойAudio_Enhanced/<stem>_enhanced.wav, 16 бит; loudnorm не ставится, если файл тише −40На сколько дБ падает уровень через 100 / 200 / 300 мс после конца фразы: больше — суше.
Мерка — solo.py tail_db, медиана по концам фраз; сухая речь — 35…50 дБ. Чистка: изолятор 90 % + 10 % живой петлички.
| Проверка | Когда | Норма | Откуда взялась |
|---|---|---|---|
| Формат исходника | до всего | pcm_f32le, 48 кГц, моно, целый файл | срезы и s24-копии теряли пики |
| Петля ингеста (трек Premiere) | 17_audio, план лент | −23 LUFS ±1; дрожание < 0,3 LU не правится; отрезок ≥ 3 с | цель Auto-Match и EBU R128; 9 LU запаса до мастера |
| Копии для распознавания | day_ingest, s2_audio | RMS −20 dBFS; копия не тише источника на 6 дБ при источнике громче −40 | YTEVO03: нормировка по пику — pyannote пуст при живом тексте |
| Вход и сдвиг изолятора | clean · dialog | вход −30 LUFS, потолок −1; сдвиг ≤ 48 сэмплов (1 мс), иначе стоп | модель роняет громкую речь; обработка задерживает звук |
| Речь после чистки целая | после dialog: ASR и слух | расшифровка заново = лист (YTCG37: 951 слово, 100 %); шипящие на месте | изолятор может съесть согласные |
| Мастер | master · qc | −14 ±1 LUFS, пик ≤ −1 dBTP, лимитер −1,5, LRA ≤ 8; autocut ±0,5; doc_cut TP ≤ −0,9; паспорт YouTube −14 ±2 | 17_audio/standard.py — одно место чисел |
| Синхрон звук–картинка | qc | autocut ≤ 20 мс на планах ≥ 3 с; headless ≤ 40 мс; doc_cut 0 ± 2 мс к WAV мастера | подрезка в плеере дала рассинхрон 30 мс |
| Собранная речь = лист | verify · asr · verify.py | headless: 3 + 3 слова у стыка, < 5 из 6 → флаг; solo: вся программа; doc_cut и story_cut: края реплик; autocut — ASR сборки нет | вырезанные слова нашёл клиент |
| Тишина и мёртвые каналы | qc · listen · 17_audio | silencedetect −55 дБ / 2 с; −91 дБ = цифровой ноль; канал тише −50 мёртв; полоса тише −45 LUFS — не петличка говорящего | FX3 утром писал ноль в L; TX02 на −49…−51 — шум зала |
±1 — standard.py; ±2 — паспорт YouTube («на грани»); autocut сверяет ±0,5
doc_cut допускает TP ≤ −0,9
autocut — на планах ≥ 3 с; doc_cut — 0 ± 2 мс к WAV мастера
17_audio/standard.py, строка 14: «одна поправка на полосу сцены, эффектом на клипе (исходник 32 float не трогаем)»; README 17_audio: «базово выравниваем в Premiere, не трогая исходник (петлички пишутся в 32 float — запас есть в обе стороны)»; audio_level_plan.py: «Исходники не трогаются никогда»_autocut_cache/…/audio/clean/, doc_cut — в stems/{key}__raw|__iso.wav, solo — заново на каждом прогоне; story_cut берёт звук клипаstandard.py меняется явноAudio_Enhanced/<stem>_enhanced.wav; лестница _v1_Orig … _v4_Warm; doc_cut __raw / __iso; autocut <кэш>/stems/<имя>__orig.wavtx_strips_source и пишет бэкап ингеста; relav2: «пишем в стейджинг, подмена — отдельным шагом»99_Pipeline/DJI_Audio/ с суффиксом в имени · папка-сосед с теми же именами · только в проекте фильма, но одна на все движки| Файл | Что хранит | Кто пишет |
|---|---|---|
17_audio/standard.py + README | единственное место чисел: ингест −23, мастер −14 / −16, потолки, гейты речи; VERSION и UPDATED | сессия после решения Романа; движки импортируют, копий не заводят |
sound.speech и music в {CODE}_cut_job.json | выбранная чистка: clean, wet, eq, comp; трек и уровни музыки | сессия после выбора Романа на слух |
autocut: clean/<стем>.json, variant_choice.json, music/choice.json, audio_report.json | уровень речи, усиление, пик, сдвиг изолятора; выбор варианта и музыки (запоминается); громкость, LRA, источники стемов | audio.py; руками — --variant, --theme, --bed |
08_Cut/sound_dialog_<tag>.json, sound_master_<tag>.json, verify_<tag>.json, sync.json | усиления по дублям, хвост комнаты до и после, мастер и ok, сверка речи, сдвиг к камере | headless, solo, doc_cut, story_cut — имена свои, смысл один |
рецепты в коде: RECIPES, RECIPE_C, SPEECH_EQ, CHAINS | рецепт C, тембр lav_warm, цепочки lav / car / cam / pub | сессия после A/B Романа; умолчание — только его выбор |
| память: feedback_sound_fix_float_source, reference_float_lav_level_rms, feedback_lav_room_echo_isolate, хаб reference_hub_audio_sync | правило источника, уровень по RMS, эхо и изолятор, рецепт C и процесс выбора | сессия сразу после слов Романа |
level=disabled; limit 0,95 при attack 5 мало — пик снова в 0 dBFS, нужно 0,85 и attack 1s2_audio.py · audio_io.pylatency=1; solo denoise: 1199 сэмплов (25 мс) сняты корреляцией; мастер solo — снятие задержки лимитераYTCG37 · solo.py unlagTranscription/<клип>_AUDIO.wav от 0102 — s16, -ac 2, первый поток; 4 дорожки адаптера свелись бы в две; _orig.wav не берётсяпо коду sc_listen.py; на фильме не провереноV=~/YTAI/environment/.venv_transcribe/bin/python; X=~/YTAI/scripts/999_extra E=~/YTAI/scripts/05_editing; AC=$E/0510_autocut; HC=$E/0510_headless_cut; DC=$E/0511_doc_cut; SC=$E/0511_story_cut $V $DC/sync.py measure --job $J # сдвиг петличек к звуку камеры: окна 10 с через 45 с → 08_Cut/sync.json $V $AC/audio.py stems --cut … --cache … # источники → моно float32 48 кГц во всю длину; оригинал PCM вместо прокси после сверки $V $AC/audio.py clean # речь к −30 LUFS, alimiter level=disabled, изолятор → raw · soft · clean · warm $X/bin/voice_isolate in.wav out.wav --wet 100 --quality high # AUSoundIsolation; последняя строка stdout — JSON с задержкой и скоростью $V $HC/solo.py dialog --job $J # clean: isolate — голос без комнаты + 10 % живой петлички → dialog_<tag>.wav $V $AC/audio.py assemble # речь по листу + тон сада + музыка → сведение → мастер mix_v4.wav и стемы $V $SC/sc_sound.py dialog $P · nat $P · music $P · master $P # story_cut: стемы по микрофону, живой звук, музыка по энергии, мастер $V $HC/solo.py verify --job $J # Whisper слушает собранную речь целиком, сверка с листом $V $SC/sc_qc.py asr $P # сверка речи с листом по краям кусков — через mlx_queue.py
Тяжёлые стадии сами встают в очередь рендеров (render_gate.py); распознавание — только через mlx_queue.py: одна локальная модель за раз.
$V $AC/audio.py ladder --what sound,music,edges # → ~/Downloads/<CODE>_v4_choices/{sound,music,edges}/ + страница выбора $V $AC/audio.py assemble --variant garden=warm --theme ID --bed ID # выбор руками; запоминается в variant_choice.json и music/choice.json $V $HC/solo.py sound_ab --job $J --take E # пять вариантов куска 24 с на −16 LUFS → ~/Downloads/<CODE>_sound_choice/ # выбор Романа → задание, ключ sound.speech: {"clean": "isolate", "wet": 0.9, "eq": "lav_warm", "comp": "soft"}
$V $DC/sound.py stems --job $J · dialog · music · master # петличка +20 дБ → __raw + __iso; wet 0,72 / 0,86; мастер −14, s24 ffprobe -v error -show_streams файл.wav | grep codec_name # источник обязан быть pcm_f32le