SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|
2025|01|02|03|04|05|06|07|

2025-07-29(Tue) エンジン音を理詰めする

  次はサウンド関係に手を付けるかなぁ、とかいいながら、なぜか加速の物理挙動を組み込み始めたら止まらなくなってしまい、ほぼ完璧に組み込みを完了してしまったのだが、それはまた後日に扱うことにして、サウンド関係について少し進めることにする。

  F1ゲームでサウンドといえば、重要なのは走行音だ。特に実装したいのは「ドゥ、ドゥ、ドゥ、ドゥーン」という連続シフトダウンの操作の効果音だが、まずは通常のエンジン音を実装するのが先だ。

  エンジン音とは何か。雑に言えば「ブゥーン」という尻上がりのノイズ、なのだが、加速の物理挙動の組み込みがあまりに興味深かったので、効果音も適当に付けようという気にならなくなってきた。ここは理詰めで、可能な限りリアルな効果音を付けてみたい。

  エンジンとは「吸気、圧縮、燃焼、排気」の繰り返しを回転運動に変換する機構で、支配的な音は「燃焼」時の破裂音だ。なので、音色は「鋸歯状波」に近くなる。ノコギリのように素早く立ち上がって、スッと消える。そして、アクセルを踏んでエンジンの回転が高まると、破裂音の発生間隔が狭まる。つまり、周波数が高くなり、低音から高音に遷移していく。それが「ブゥーン」と「尻上がり」な音になる理由だ。

  基本となるパラメータはエンジンの回転数だ。rpm。Round Per Minute。1分間の回転数。3000rpmなら、50回転/秒。では、50Hzかというと、それは違う。4サイクルエンジンは2回転に1回しか燃焼しないからだ。では、25Hzかというと、それも違う。4気筒エンジンなら、基本的に各気筒が順次に燃焼するので、その4倍。100Hzが正解である。

  そこまでわかったところで音を出してみる。効果音の生成には、以前に作ったり、改良したりした、自製のツールを使う。記述は以下。

@length = 2
 
car1 = it = {}
it[:device] = 'generate'
it[:length] = @length
it[:type] = 'sawtooth'
it[:freq] = [100]
 
@connection = [ car1 ]

  こんな音になった。まぁ、ロードスターを含む、小型車のエンジン音、といわれれば、まぁ、そんな風に聴こえなくもない。波形はこう。

  画像の説明

  んが、これ「ノコギリのように素早く立ち上がって、スッと消える」の逆になっている。欲しいのは、こうではないか?

  画像の説明

  つうわけで、ツールに「sawtooth_r」を追加で実装してみる。

#---------------------------------------------------------------
#
#   鋸歯状波
#
wgens['sawtooth'] = Proc.new {|dev, p|
    p += 0.5
    (p - p.to_i) * 2 - 1                        # output: -1.0 - 1.0
}
 
#---------------------------------------------------------------
#
#   鋸歯状波(逆、破裂音?)
#
wgens['sawtooth_r'] = Proc.new {|dev, p|        # p: 波形の周期位置、最初の波形の中点なら 0.5、10 周期目の終点なら 9.9
    1 - (p - p.to_i) * 2
}

  こんな音になった……んが、聴感上では違いがわからないな。鼓膜が感知するのは経時的な圧力変化だから、そういうもんなのかもな。と、ここで、加速させてみる。2秒で3000rpmから6000rpmへと。

@length = 2
 
car1 = it = {}
it[:device] = 'generate'
it[:length] = @length
it[:type] = 'sawtooth_r'
it[:freq] = [100, 200]
 
@connection = [ car1 ]

  こんな音になった。チープだが悪くない。つうか実際、黎明期のレースゲームの走行音って、まさにこんな音だよね。

  とりあえず、ロードスターはコレでいいとして、次はF1マシンだ。F1マシンは12000回転くらいまで回して走る。そんなら倍の400Hzかといえば、これまた違う。6気筒エンジンなので、その1.5倍。600Hzになる……はずなのだが、オンボード映像の音声を解析してみると300Hzが支配的なんだよなぁ。どうやら、バンク角90度のV6という特性が影響しているらしい。ついでなので、10500〜12000回転でシフトアップする音を作ってみる。

@length = 1
 
car1 = it = {}
it[:device] = 'generate'
it[:length] = @length
it[:type] = 'sawtooth_r'
it[:freq] = [262, 300]
 
@connection = [ car1 ]
$ sox 6kitou_f1.wav 6kitou_f1.wav 6kitou_f1.wav 6kitou_f1_shift3.wav

  こんな音になった。3回繰り返しているだけだが、シフトアップしているようにも聴こえなくもない。

  これだけでも十分に高音だが、1990年代のフェラーリは17000回転も回して馬力を稼いでいた。しかも12気筒。フェラーリサウンドってやつだ。こっちも、オンボード映像の音声を解析してみると理論値の半分で850Hz。13000〜17000回転でシフトアップする音を作ってみる。

it[:freq] = [650, 850]

  こんな音になった。カン高いフェラーリサウンドの片鱗を感じられなくもないが、こんなんじゃあない。主な理由は倍音成分がないからだ。つづく。