Pull to refresh

Comments 28

Интересно эмуляторы гитары генерирую заранее заданный звук или всё-таки как-то синтезируют. Это довольно затратное мероприятие. Пример в спойлере

Вайб-струна

Заходим в Гугелпоиск, переводим в режим ИИ и просим напитонить скрипт, который имитирует струну как решение системы дифф уравнений в частных производных. Переводим Gemini в режим Pro - хоть там и лимитное количество запросов но более чем достаточно в этом режиме. Он даже меня поправил по количеству точек - это сделано намеренно, чтобы сразу оценил обусловленность задачи и её сходимость. Идея: квантовать струну конечными элеметами, использовать обычную эластичность и рассеяние в воздухе тонким элементом, зависящее от скорости (например, по формуле Стокса) ну и куча мелких ограничений чтобы посчитал основную ноту. Вывести в пайсаунд не захотел так как это явно не реалтайм но предложил в wav-файл. На выходе звук скорее напоминает телефонный зуммер но по мере затухания что-то приближается к струне. Ну и соответственно для общего звука собираем по теореме Пифагора все волны от каждого элемента струны.

Промпт:

let solve a string equation. string is 128 points joints. Use string law for elasticity. use air dissipation simulation damping velocity dependent. pde solver numpy. from each point make a collector point distance equal string length. time duration 10s frequency 440 Hz estimate parameters pde damping time 3s. Initial condition triangle form form of string about 1/10 length perpendicular direction zero speed. Timestep 4400 Hz. Convert to 44 kHz upscaling. Collect to pysound make output.

import numpy as np
import scipy.signal
import scipy.io.wavfile as wavfile
import matplotlib.pyplot as plt

# --- 1. Configuration & Parameters ---
freq_target = 440.0       # Hz
duration = 10.0           # Seconds
L = 1.0                   # String length (m)
N_points = 128            # Spatial grid size
damping_time = 3.0        # Time to decay to 1/e (Air friction)
pluck_pos_ratio = 0.1     # 1/10 length
sample_rate_out = 4400    # Requested simulation capture rate
audio_rate_final = 44100  # Final audio output rate

# Derived Physics Parameters
c = 2 * L * freq_target   # Wave speed (m/s) -> f = c / 2L
dx = L / (N_points - 1)   # Spatial step

# CFL Stability Logic (Courant-Friedrichs-Lewy condition)
# We need c * dt / dx <= 1.0 for stability.
dt_critical = dx / c
dt_physics = dt_critical * 0.9  # Safety margin
oversample = int(np.ceil((1/sample_rate_out) / dt_physics))
dt = 1 / (sample_rate_out * oversample) # Actual physics timestep

print(f"Stability: Physics running at {1/dt:.0f} Hz (Oversample: {oversample}x)")

# Damping Coefficient (Linear Air Drag: u_tt + gamma * u_t = c^2 * u_xx)
# Decay envelope is exp(-gamma * t / 2). For 1/e at 3s: gamma = 2 / 3.
gamma = 2.0 / damping_time

# --- 2. Initialization (Triangle Pluck) ---
x = np.linspace(0, L, N_points)
u = np.zeros(N_points)       # Current position
u_prev = np.zeros(N_points)  # Previous position (for velocity)

# Setup Triangle Wave
pluck_idx = int(N_points * pluck_pos_ratio)
height = 1.0
# Rise
u[:pluck_idx] = np.linspace(0, height, pluck_idx)
# Fall
u[pluck_idx:] = np.linspace(height, 0, N_points - pluck_idx)

# Initial Velocity is zero, so u_prev = u roughly (ignoring first half-step acceleration)
u_prev = u.copy()

# Precompute Finite Difference Constants
# u_next = (2 - 2*C^2)*u + (C^2)*u_left + (C^2)*u_right - u_prev ... damped
C_sq = (c * dt / dx) ** 2
# Damping factors: centered difference for u_t
# (u_next - u_prev) / 2dt -> introduces damping
A = 1 + gamma * dt / 2
B = 1 - gamma * dt / 2
inv_A = 1.0 / A

# --- 3. The PDE Solver Loop ---
num_frames = int(duration * sample_rate_out)
raw_history = np.zeros((num_frames, N_points))

# Collector Setup (Acoustic Propagation)
# Listener is at (L/2, L) -> Distance L from center, perpendicular
listener_pos = np.array([L/2, L])
source_positions = np.column_stack((x, np.zeros_like(x)))
distances = np.linalg.norm(source_positions - listener_pos, axis=1)
# Delays in samples (at output rate)
delays = (distances / 343.0) * sample_rate_out # 343 m/s speed of sound
delays = delays.astype(int)

print("Solving PDE...")
current_phys_step = 0
for i in range(num_frames):
    # Run physics sub-steps
    for _ in range(oversample):
        # Vectorized wave equation step [1:-1] excludes fixed endpoints
        u_next = np.zeros_like(u)
        u_next[1:-1] = (
            inv_A * (
                (2 * u[1:-1]) + 
                (gamma * dt / 2 * u_prev[1:-1]) - # Term adjustment for B
                u_prev[1:-1] * (1 - gamma * dt/2) + # This simplifies algebraically usually
                C_sq * (u[2:] - 2 * u[1:-1] + u[:-2])
            )
        )
        
        # Standard Damped FDTD update:
        # u[n+1] = [ (2u[n] + (gamma dt/2 - 1)u[n-1] + C^2(u[x+1] - 2u + u[x-1])) ] / (1 + gamma dt/2)
        term_inertial = 2 * u[1:-1]
        term_damping_prev = (gamma * dt / 2 - 1) * u_prev[1:-1]
        term_stiffness = C_sq * (u[2:] - 2 * u[1:-1] + u[:-2])
        
        u_next[1:-1] = (term_inertial + term_damping_prev + term_stiffness) / (1 + gamma * dt / 2)

        # Update states
        u_prev = u.copy()
        u = u_next.copy()
        
    # Store state at the user-requested 4400 Hz
    raw_history[i, :] = u

# --- 4. Acoustic Collection (Summation) ---
# Simple sum of acceleration or displacement at collector distance
# We will map the time-history to the listener with delay
collector_signal = np.zeros(num_frames + np.max(delays) + 100)

print("Aggregating acoustic paths...")
for p in range(1, N_points - 1): # Skip endpoints (fixed)
    # Add contribution from point p shifted by delay
    # Attenuation by distance (1/r law)
    contribution = raw_history[:, p] / distances[p]
    # Simple delay line injection
    start_idx = delays[p]
    end_idx = start_idx + num_frames
    collector_signal[start_idx:end_idx] += contribution

# Trim tail
collector_signal = collector_signal[:num_frames]

# --- 5. Upscaling & Output ---
print("Upscaling to 44.1 kHz...")
# Resample from 4400 Hz to 44100 Hz
samples_target = int(len(collector_signal) * audio_rate_final / sample_rate_out)
audio_final = scipy.signal.resample(collector_signal, samples_target)

# Normalize to 16-bit PCM range
audio_final = audio_final / np.max(np.abs(audio_final)) * 32767
audio_final = audio_final.astype(np.int16)

# Save
output_filename = "string_simulation_440hz.wav"
wavfile.write(output_filename, audio_rate_final, audio_final)
print(f"Saved: {output_filename}")

Волна в струне, там же можно прямо промоделировать как это происходит

Разумеется, сама по себе гитара - это резонатор, его потенциально можно сделать некой передаточной функций читающей концы струны и дающей обратную связь на струну же, так как 3Д моделирование в конечных элементах это уже неподъёмная задача тем более в реалтайм. Далее уже можно составлять простенькие модельки, есть даже SPICE симуляторы для гитар, имитирующие различные примочки из журналов а-ля "Радио" и прогоняющие сигнал через виртуальные транзисторы и операционники.

есть и синтезаторы и сэмплеры. Я пользуюсь библиотекой METAL-GTX чтобы в MIDI набросать гармонию и представлять себе как оно потом звучать будет.

Вот тут судя по фамилии наш соотечественник этим занимается. Можно нарисовать схему, скормить ей тестовый NAM файл, потом обучить нейросеть и поиграть в получившийся звук без необходимости паять реальное устройство.

https://kpp-tubeamp.com/

Вот именно ради таких статей я до сих пор захожу на хабр. На wham! вроде даже натыкался в детстве, но дальше потыкать дело не ушло.

У нас, в кругах юных металлистов, большой популярностью пользовался screamtracker под dos (:

Спасибо, да, помню такой трэкер у друга, собсно себе захотел также и попросил того друга помочь мне подобрать запчасти будущего компьютера на Савёле. Но когда наконец собрал, это уже была винХР, кейкволк и книжка Петелиных про него.

Дмитрий, простите, а у Вас случаем нет блога? Просто очень уж душу греет всё это. Гитарный мастер, техника. Просто кажется, что у Вас есть что рассказать - не только в формате технических статей, а что-то, что можно почитать и послушать после кода, налив 50 вискаря, поигрывая блюзики вечером?

Когда-то был на ли.ру, но, скорее, личный и давно удалён за неактивностью. На хабр давно хотел влезть с техническими программистскими делами, но уже 6 лет как ушёл из офиса в свою мастерскую на полный день и как-то уже не очень актуально. Впрочем, гугл постоянно подсовывает мне гитарные статьи с хабра. Может и актуально. Дело не шибко денежное, работаю почти всё время, еле наскрёб на какую-то группу пожужжать. Возможно надо бы где-то писать. Порой есть чем поделиться, что по гитарам интересно, что по музыкальным примочкам. Вот, например, на репетиции таскаю "кемпер для бомжей" - Raspberry PI со звуковухой pisound и установленным внутри pipedal. Как обеспечил группе из 7 человек независимый стерео мониторинг в уши без задержек и с веб-интерфейсом за примерно 250 евро, включая лаптоп и все соединительные кабеля. Как фиксил FFADO и добавлял фичи, в последнем релизе меня даже упомянули в контрибуторах. Как писал прошивку для намоточного станка для датчиков на ESP32. Всё это чисто ради хобби, совмещённого с гимнастикой мозгов. Но потраченное время сильно бьёт по семейному бюджету, так что даже если и буду писать, то не слишком часто.

Спасибо Большое!

Линукс так и не смог запустить плагины от Изотоп Озон и Waves, так что говорить о сведении и мастеринге на Линукс пока глупо. И это пока уже долгие годы. Так что с записью гитары это все пустое. Потому что на сведение и дальнейший мастеринг отдавать другому человеку, у которого мак или винда. Как то так.

Что есть уникального в изотоп и вавес, чего нельзя сделать другими плагинами?

Изотоп в принцепи можно, вавес тоже, но их, вавеса компрессоры и ssl эквалайзеры лучшие. Ну на мой взгляд. И по звуку и по нагрузке на процессор. А вот аналогов FabFilter Pro-Q 3 увы нет. Все остальное даже не компромис. Ещё я не ставил свои эмуляторы усилителей и плееры импульсов. Но они скорее всего заведутся. Так как там нет косяков, нет своей программы -магазина. Я бы с радостью перевел бы студию на Линукс, благо там ниже задержка и меньше есть ресурсов. Но пока именитые производители не делают vst под линь, это теряет смысл. Да, можно дома поиграть и записать гитару, плохенько, может даже DI сигналом с обработкой на своих импульсах. Но для чего то серьезного не хватает инструментов. Но, допускаю, что может для лёгких стилей хватит. Но для метала, когда надо свести хотя бы 12 дорожек, на которых целые цепи вст, а потом всё ещё отмастерить на мастершине, доступных плагинов не хватает. Увы.

Хорошие у них маркетолухи - раз вы такое пишите) Зато у вас есть большой потенциал для новых открытий

Дело не в маркетологах, а в том что каждый набирает себе набор vst методом проб и ошибок. Если bus compressor можно взять не от вейвса, а, скажем от Натив инструмента, тоже не заведется через Вайн, то аналогов FabFilter Pro-Q 3 я не нашел. Не, наверное можно купить лицензию и тогда может через Вайн встанет, но это не путь воина.

Помнится, для kx project писал плагины и один из них даже попал в официальный дистрибутив. Ну а сейчас интереснее играть в живой настоящий комбик (Vox Valvetronix в частности), где все необходимые эффекты уже есть на борту и приятно настраиваются крутилками.

P.S. Спасибо за стробо-тюнер - не слышал о таких раньше. Теперь, как программисту, интересно написать свой)

Ну, если суть только в крутилках, то у меня для вас хорошие новости. M-audio projectmix замечательно крутит любые крутилки, в том числе плагинов. Думаю, любой подобный контроллер подойдёт. В том числе можно запрограммировать коробочку с энкодерами и кнопками самому, протоколов разных есть.

Суть конечно же в звуке - гитарный динамик в деревянной коробке звучит и ощущается не так, как спикер-симулятор в наушниках.

Это да. Минус симуляторов в том, что от них штаны не шевелятся при игре. Обычный комбик у меня, конечно, есть, Laney 30-ваттный. Проверять готовые гитары клиентам даю именно в него. Только вот репетиции и концерты всё равно в затычках. С болью вспоминаю концерты, когда я целиком и полностью зависел от чувака где-то там за пультом в зале, которому до лампочки как кто кого как слышит на сцене, он это даже проконтролировать никак не может. Сегодня уже редко встретишь группы без IEM. Ну, а что хорошо для металлики, подойдёт и мне. Помню, как Кирилл Остапов рассказывал, что был в 2007м рядом с оператором в Олимпийском на Оззи и BLS, видел там рэковые процессоры LINE6 в стойках, а то, что там коробочки на сцене - бутафория. Я сам там не был, верю на слово, за что купил - за то и продаю. С IEM группа может подавать материал гораздо качественней, чем играя в каше звука, с трудом различая друг друга в ней. А самому в гараже - да, приятней грохотать в ламповый стэк. Тот же Valvetronix по сути тот же софтовый симулятор с широкополосным динамиком. Может архитектурно, конечно, реализован и на какомнибудь FPGA или на собственном DSP, не в курсе, но не аналоговый точно. Ну а хорошо записать настоящий ламповый усилитель с кабинетом неизмеримо сложнее, чем в NAM.

В Valvetronix лампа есть и она там не бутафорская - по звуку и динамике слышно, да и выбирал его не из-за лампы, а чисто по (чистому) звуку среди прочих той же ценовой категории. На большой сцене - да, выступать не приходилось, а тем более с группой. Максимум на пьянках развлекать народ и самому не сильно трезвым)

Не холивара ради, если мне память не изменяет, лампа там только в мощнике, а преамп цифровой.

Да. Интересный вопрос в том, ограничились они только АЧХ или эмуляция чуть более строгая. Сравнить с оригинальным АС30 возможности пока не было.

Спасибо очень интересно. Хочется дополнить, на ютубе есть ролик на канале hardsound где автор из слабой офисной машины делает гитарный процессор с минимальной задержкой и каким-то монструозным софтом для симуляции примочек, усилителей, кабинетов, путём установки в систему специального быстрого ядра. Мне что еще особенно понравилось, он показал там как одновременно можно записывать чистый звук и обработанный, слушать обработанный.

(Ссылку сам бы вставил, но сейчас нет технической возможности смотреть YT, найти не сложно вроде бы "Линукс для гитариста").

Начиная с ядра 6.18 RT патчи были интегрированы в майн ветку и надобность в установке отдельного RT ядра отпала. Есть исследование, показывающее, что даже самый реалтаймовый liquorix оказался медленней, чем ванилла 6.18

https://www.phoronix.com/review/linux-618-liquorix/5

Тот канал я конечно смотрел. Потому и сам пользуюсь конечно самодельным процессором на основе Raspberry PI с звуковой картой pisound и беспроводным MIDI контроллером M-VAVE. Тоже об этом напишу как-то.

pisound
pisound
pistomp
pistomp

а результат мы потом крутили на дискотеке в колледже

И как фидбек от благодарной публики?

Вполне положительно. Настолько, что следующее выступление уже было живьём на втором курсе. С живыми барабанами и басом. 35 лет назад было дело...

Ну что же здорово, не сохранились записи с того времени?

к сожалению, нет.

Дмитрий, а не подскажите хороший на ваш взгляд ресурс, по-русски желательно, по Ardour, для изучения этого DAW?

Интерсно, между обычной убунтой и "убунту studio" есть какая-то разница по ядру или его настройкам? Или отличия только в пакетах, которые кладут в базовый дистрибутив?

Sign up to leave a comment.

Articles