押されたボタンに応じて 4 つの異なるトーンを再生する非常に単純なプログラムがあります。複数のトーンまたは同じトーンを立て続けに再生すると、不快なクリック ノイズが発生することがわかりました。これらのクリックがオーディオ サンプルに存在しないことを確認しました。これは間違いなく、クリップを次々とすばやく再生することが原因です。
グーグルで調べた後、クリックはクリップ間のピッチの急激な変化によるものであると確信しています. 問題のあるオーディオからの再生の波形を見ると、次のクリップを開始する前に、クリップが最初に数分の 1 の間キャンセルされているように見えます。これが特に明白と思われるセクションを強調しました。
これらのオーディオ クリックを紹介するクリップは、こちらからダウンロードすることもできます。
私のコードはとてもシンプルです。XInput を使用して、再生するトーンを決定する接続されたコントローラーから入力を読み取り、WinMM を使用して wav ファイルからサウンドを出力しています。これは D プログラミング言語で書かれていますが、できるだけ C に似せて混乱を避けるために、D 固有の機能を使用しないように変更しました。
SHORT keyPressed(int vkey)
{
enum highBit { val = 0x8000 }
return cast(SHORT)(GetKeyState(vkey) & highBit.val);
}
enum Button
{
DPAD_UP = 0x0001,
DPAD_DOWN = 0x0002,
DPAD_LEFT = 0x0004,
DPAD_RIGHT = 0x0008,
START = 0x0010,
BACK = 0x0020,
LEFT_THUMB = 0x0040,
RIGHT_THUMB = 0x0080,
LEFT_SHOULDER = 0x0100,
RIGHT_SHOULDER = 0x0200,
A = 0x1000,
B = 0x2000,
X = 0x4000,
Y = 0x8000,
}
struct XINPUT_GAMEPAD
{
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
}
struct XINPUT_STATE
{
DWORD dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
bool isPressed(int button)
{
return cast(bool)(Gamepad.wButtons & button);
}
}
int main()
{
HANDLE xinputDLL = initXinput();
XINPUT_STATE oldState;
XINPUT_STATE newState;
while (!keyPressed(VK_ESCAPE))
{
oldState = newState;
XInputGetState(0, &newState);
enum flags { val = SND_ASYNC | SND_FILENAME | SND_NODEFAULT }
if (newState.isPressed(Button.A) && !oldState.isPressed(Button.A))
{
PlaySoundA(toStringz("Piano.ff.A4.wav"), null, flags.val);
}
if (newState.isPressed(Button.B) && !oldState.isPressed(Button.B))
{
PlaySoundA(toStringz("Piano.ff.B4.wav"), null, flags.val);
}
if (newState.isPressed(Button.X) && !oldState.isPressed(Button.X))
{
PlaySoundA(toStringz("Piano.ff.C5.wav"), null, flags.val);
}
if (newState.isPressed(Button.Y) && !oldState.isPressed(Button.Y))
{
PlaySoundA(toStringz("Piano.ff.F4.wav"), null, flags.val);
}
}
denitXinput(xinputDLL);
return 0;
}
クリック音のソースに関して私が正しいと仮定すると、解決策は各サンプルを次のサンプルにフェードインさせることだと思います。ただし、WinMM のドキュメントは比較的まばらなようで、経験が浅いため、これを行う方法がわかりません。
各サンプルが次のサンプルにフェードインするようにオーディオ サンプルを再生するときのクリックの問題の解決策はありますか? もしそうなら、WinMM を使用してこれを達成するにはどうすればよいですか? そうでない場合、私が試すことができる別の解決策はありますか?