トップ回答者
[C#]任意の周波数と音量でスピーカを鳴らす

質問
-
質問 任意の周波数と音量でスピーカを鳴らす簡便な方法を教えてください。
要件
・任意の周波数と振幅で正弦波を定義し、スピーカに連続で出力したい。
・周波数あるいは振幅は、任意に変更できるようにし、その時も途切れること無く連続した出力が得られるようにしたい。
・関数の定義例
static void SetSound(float hz,float volume) // 周波数と音量を設定(変更)します。
static void SoundOn() // 連続出力を開始します。
static void SoundOff() // 連続出力を停止します。
・実行対象OS Windows7 sp1以降、Windows8およびWindows8.1質問の背景
・あらかじめ準備したWAVEファイルを再生する方法では演算で生成した波形を音声出力する方法と相性が悪いため、もっと簡便で効率的な方法を見つけたい。
・WindowsAPIのBeepSoundは音量が設定できず音質も悪いので、もっと高機能な方法を知りたい。
・(できれば)この機会にMicrosoftが推奨している新しい音声プラットフォーム(DirectX Audio)について知りたい。
C#開発者
回答
-
Win32 APIのwaveOut系で波形データを直接制御・出力できると思います。C#から直接Win32 API関数をコールする場合はP/Invokeを使います。
DirectX Audioの中で直接波形データを操作できるローレベルAPIはDirectSoundとXAudio2ですが、前者は別に新しくはありません。むしろ枯れています。DSoundやXAudioをC#から使うのであればManaged DirectX 1.1を使うか、C++/CLIでラップしてやる必要があります。MDXの開発者向けランタイムは旧DirectX SDKに同梱されてますが、MDXを使ったアプリを再配布する場合はインストーラーにランタイムのインストール機能を含めたり、利用者にエンドユーザーランタイムをインストールしてもらったりする必要があります。
いずれにせよ、C#でWin32 APIやDirectX APIを使うよりも、C++でそれらを使うほうが楽だし情報やサンプルを集めやすいです。特にC#でDirectXを扱うのは茨の道です。
あとはXNAでXAudio2を使う方法もありますが、MDX同様に開発が終了しているのが難点です。
すべての返信
-
Win32 APIのwaveOut系で波形データを直接制御・出力できると思います。C#から直接Win32 API関数をコールする場合はP/Invokeを使います。
DirectX Audioの中で直接波形データを操作できるローレベルAPIはDirectSoundとXAudio2ですが、前者は別に新しくはありません。むしろ枯れています。DSoundやXAudioをC#から使うのであればManaged DirectX 1.1を使うか、C++/CLIでラップしてやる必要があります。MDXの開発者向けランタイムは旧DirectX SDKに同梱されてますが、MDXを使ったアプリを再配布する場合はインストーラーにランタイムのインストール機能を含めたり、利用者にエンドユーザーランタイムをインストールしてもらったりする必要があります。
いずれにせよ、C#でWin32 APIやDirectX APIを使うよりも、C++でそれらを使うほうが楽だし情報やサンプルを集めやすいです。特にC#でDirectXを扱うのは茨の道です。
あとはXNAでXAudio2を使う方法もありますが、MDX同様に開発が終了しているのが難点です。 -
一般のアプリケーションですと、XAudio2よりMedia Foundationを使うかもしれません。もしくは直接叩いてしまうのならCore Audio APIです。ただしどちらにしてもsyghさんの指摘されているようにC#から直接扱えるライブラリが提供されているわけではないので、C++/CLIなりなんらかの努力が必要です。
# 私の場合、IDLを見ながら必要なinterfaceを全て定義した上で呼び出していますが…。なお、どのような方法を用いるにしても音声というのは継続的に与える必要があるため、start / stopがあるわけではありません。