結論
調べましたがよくわかりませんでした。
以下おまけ
最近C#で動画編集ソフトを作り始めたのですが
C#でマルチプラットフォームに音声再生する方法が全然ないことに気が付きました。
C#で音楽再生する定番のライブラリにNaudioというものがあるのですが、こちらはライブラリの根幹からWindowsに依存しており、MacやLinuxでは使えないようです。
https://github.com/naudio/NAudio/issues/1077
そこで、C#でマルチプラットフォームオーディオができそうな手段をいくつか試したり試さなかったりしたので以下に書いていきます。
具体的な用途としては、バッファを格納する配列に別で用意した生の音声データを書き込み、再生するようなことを想定しています。
検討したもの
GitHubのトピック検索なども用い、いくつかのライブラリを検討しました。
※検討しただけで最後まで読んでも結論は出ません
動作を試みた環境
- Windows11 64bit
- VirtualBox上で動作しているUbuntu 22.04
SharpAudio
バックエンドにWindowsではDirectSound、それ以外ではOpenALを用いる音声再生ライブラリです。
Readmeのexampleがまさに私のやりたいことそのままで簡単に扱えそうで好感触でしたが、いくつか問題がありました。
Ubuntuで動作確認ができなかった
example1行目の
var engine = AudioEngine.CreateDefault();
にてNullを返してしまう現象がUbuntu上で発生し、解決できませんでした。
OpenGLを使用する他ソフトは動作しているので、ドライバの事情ではないと思います。
バックエンドによって動作が異なる
WindowsでもOpenALをインストールした上で、先ほどのAudioEngineのインスタンス生成コードを以下のように書き換えることで、OpenALバックエンドを明示して使用することが可能です。
var engine = AudioEngine.CreateOpenAL(); //OpenALバックエンドの使用を明示
その上で、exampleを書き換え以下のようなプログラムを作成しました。
using SharpAudio;
var engine = AudioEngine.CreateDefault();
// var engine = AudioEngine.CreateOpemAL(); //OpenALバックエンドを使うとき
var buffer = engine.CreateBuffer();
var source = engine.CreateSource();
// Play a 1s long sound at 440hz
AudioFormat format;
format.BitsPerSample = 16;
format.Channels = 2;
format.SampleRate = 44100;
float freq = 440.0f;
var size = format.SampleRate;
var samples = new short[size * 2];
for (int i = 0; i < size; i++)
{
samples[i * 2] = (short)(32760 * Math.Sin((2 * Math.PI * freq) / size * i));
samples[i * 2 + 1] = (short)(32760 * Math.Sin((2 * Math.PI * freq) / size * i));
}
buffer.BufferData(samples, format);
source.QueueBuffer(buffer);
source.Play();
Console.ReadLine();
source.QueueBuffer(buffer);
Console.ReadLine();
内容としては
「440Hzの音1秒分のバッファを作成」
↓
「再生キューに追加」(再生が始まる)
↓
「適当に入力したらもう一度バッファを再生キューに追加」
といったもので、計2秒分音を再生できるはずで、実際にDirectSoundバックエンドでは正常に動作します。
が、OpenALバックエンドでは再生できるのは最初の1秒分だけで、あとから追加するもう1秒分のバッファは再生されません。
開発が止まっている
2年ほどリポジトリに動きはなく、issueを立てての上記問題解決を期待することはできません。
Bufdio
バックエンドにPortAudioというCライブラリを用いたライブラリです。
exampleのプロジェクトで動作確認を試みました。
Ubuntuで動作確認できなかった
Ubuntu上でexampleのプロジェクトを動かすとDllNotFoundExeptionが発生しました。
Program.csでライブラリのパスを指定しているようなのですが、それを見る限り正しい場所にライブラリが置かれているように見えるのですが解決できず
開発が止まっている
こちらも2年ほどリポジトリに動きがありません。
libsoundio-sharp
バックエンドにlibsoundioというCライブラリのC#ラッパーライブラリです。
Windowsで動かす場合には、実行ファイルと同じ場所にsoundio.dllが必要で、私は別のlibsoundioラッパーのリポジトリからダウンロードして使いました。
https://github.com/crojewsk/SoundIOSharp/blob/master/SoundIOSharp/libs/soundio.dll
exampleのsio-sineで動作確認をしたところ、WindowsとUbuntu双方で音を出すことに成功しました!
ただ前述した2つと比べると低レベルな記述が必要になり、難易度は高そうです。
NextAudio
試してないです。
MiniaudioSharp
これも試してないです。
MiniaudioというCライブラリのラッパーのようです。
OpenTK
著名なOpenGLのC#ラッパーですが、OpenALを使った音声再生もできるようです。
試していません。
で結局お前はどうするんだよ
マルチプラットフォーム対応諦めようかなあ
もしほかにもこういうのあるよであったり、私ならこうするであったりがあれば教えていただければ幸いです。