Частота семплирования везде 44100, но воспроизводить можно с другими частотами, это и есть питч. Например, если питч=0.8, это значит, что воспроизводится с частотой 44100 * 0.8 = 35280.
Это частоты семплирования, а есть ещё частоты двигателя, например, в первом семпле записан двигатель на частоте 300 гц, а во втором - 400 гц. Эти частоты будут при питче = 1, то есть при частоте семплирования = 44100 гц.
Если двигатель вращается с частотой 250 гц, то первый семпл нужно воспроизводить с питчем 250/300 = 0.8333333, а второй 250/400 = 0.625, тогда они совпадут без эффекта интерференции звука.
То есть нужно точно знать, какие частоты двигателя записаны в каждом семпле.
Mikle
> какие частоты двигателя записаны в каждом семпле.
А вот это уже проблема.
vindast
> А вот это уже проблема
В первом семпле 470 Гц, во втором - 585, скачай какой-нибудь камертон - и проверяй.
Mikle
> камертон
Что это?
Я нашел пак звуков где подписаны обороты, сделал все с ними, но к сожалению работает нормально только если семплить весь пак, то есть:
for (int i = 0; i < soundInSamples.size( ); i++) { float Pith = RPM / SampleRPM[i]; soundInSamples[i]->setPith( Pith); soundInSamples[i]->setGain( 1.0f); soundInSamples[i]->setWorldPosition( pos); }
Но есть артефакт с ускоряющимся звуком.
Где бы самих семплов звука взять к разным двигателям? (самому сделать не вариант).
На основе твоих двух файлов сделал демку: Звук двигателя. Есть исходник на VB6.
Можно выборочно отключать звуки.
Mikle
v = -1000 * Exp((2880 / RPM - 1) * 4)
Поясните что здесь что и почему так. Заранее спасибо.
Это формула зависимости громкости от частоты, она, в общем, фейковая, подобрана на слух, обеспечивает плавный переход с одного семпла на другой. В DirectSound громкость задаётся значениями от -10000 (тишина) до 0 (максимальная громкость) по логарифмической шкале. В OpenAL, так понял, от 0 до 1 по линейной шкале? Тогда придётся подбирать формулу самому.
2880 - середина диапазона (среднее геометрическое между 1000 и 8000).
По моему во многих играх звук машины при переключении скоростей звучит как быстрое затухание текущей скорости + медленное нарастание следующей скорости (в плане громкости).
Я вот почитал и подумал, может дело в том что громкость не линейная, а логарифмическая? И это значит что нужно интерполировать не линейно...
Mikle
> так понял, от 0 до 1 по линейной шкале
Вот я и не знаю.
vindast
> Я вот почитал и подумал, может дело в том что громкость не линейная, а
> логарифмическая? И это значит что нужно интерполировать не линейно...
У тебя там главная проблема - несоответствие питчей, а не громкостей.
Mikle, эту проблему решил, тем способом, о котором Вы говорили.
Функция такая, это единственный рабочий вариант, который дает более-менее нормальный результат.
Но нужно переработать, и сделать интерполяцию только по двум соседним семплам, но линейная интерполяция громкости дает артефакт.
inline void update(const float& RPM, const float& MINRPM, const float& MAXRPM, const float& trotle, const vec3& pos, const vec3& velocity) { for (int i = 0; i < soundInSamples.size(); i++) { float Pith = RPM / SampleInRPM[i]; soundInSamples[i]->setPith(Pith); float gain = 1.0f - abs(RPM - SampleInRPM[i]) / (MAXRPM - MINRPM); if (gain < 0.0f) { gain = 0.0f; } soundInSamples[i]->setGain(gain); soundInSamples[i]->setWorldPosition(pos); soundInSamples[i]->setVelocity(velocity); } }
vindast
Давай на "ты".
Попробуй как-то так, когда RPM лежит между SampleRPM[ i ] и SampleRPM[i + 1]:
SampleGain[i + 1] = (RPM - SampleRPM[i])/(SampleRPM[i + 1] - SampleRPM[i]); SampleGain[i] = 1 - SampleGain[i + 1];
Mikle, это линейный, да, я так и делал.
Позже залью видео где слышен косяк.
Mikle
> Давай на "ты".
окей )
Тема в архиве.