【未解決】C#でマルチプラットフォーム音声再生する選択肢が少ない

# 結論
調べましたがよくわかりませんでした。

# 以下おまけ


最近C#で動画編集ソフトを作り始めたのですが

https://github.com/SousiOmine/Metasia

C#でマルチプラットフォームに音声再生する方法が全然ないことに気が付きました。

C#で音楽再生する定番のライブラリにNaudioというものがあるのですが、こちらはライブラリの根幹からWindowsに依存しており、MacやLinuxでは使えないようです。
https://github.com/naudio/NAudio/issues/1077

そこで、C#でマルチプラットフォームオーディオができそうな手段をいくつか試したり試さなかったりしたので以下に書いていきます。
具体的な用途としては、バッファを格納する配列に別で用意した生の音声データを書き込み、再生するようなことを想定しています。

## 検討したもの
GitHubのトピック検索なども用い、いくつかのライブラリを検討しました。
※検討しただけで最後まで読んでも結論は出ません

#### 動作を試みた環境
- Windows11 64bit
- VirtualBox上で動作しているUbuntu 22.04

### SharpAudio  

https://github.com/feliwir/SharpAudio

バックエンドにWindowsではDirectSound、それ以外ではOpenALを用いる音声再生ライブラリです。  
Readmeのexampleがまさに私のやりたいことそのままで簡単に扱えそうで好感触でしたが、いくつか問題がありました。

##### Ubuntuで動作確認ができなかった
example1行目の
```csharp
var engine = AudioEngine.CreateDefault();
```
にてNullを返してしまう現象がUbuntu上で発生し、解決できませんでした。
OpenGLを使用する他ソフトは動作しているので、ドライバの事情ではないと思います。

##### バックエンドによって動作が異なる
WindowsでもOpenALをインストールした上で、先ほどのAudioEngineのインスタンス生成コードを以下のように書き換えることで、OpenALバックエンドを明示して使用することが可能です。

```csharp
var engine = AudioEngine.CreateOpenAL();  //OpenALバックエンドの使用を明示
```

その上で、exampleを書き換え以下のようなプログラムを作成しました。
```csharp:Program.cs
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の音１秒分のバッファを作成」
↓
「再生キューに追加」（再生が始まる）
↓
「適当に入力したらもう一度バッファを再生キューに追加」

といったもので、計２秒分音を再生できるはずで、実際にDirectSoundバックエンドでは正常に動作します。

が、OpenALバックエンドでは再生できるのは最初の１秒分だけで、あとから追加するもう１秒分のバッファは再生されません。

##### 開発が止まっている
２年ほどリポジトリに動きはなく、issueを立てての上記問題解決を期待することはできません。

### Bufdio

https://github.com/luthfiampas/Bufdio

バックエンドにPortAudioというCライブラリを用いたライブラリです。
exampleのプロジェクトで動作確認を試みました。

##### Ubuntuで動作確認できなかった
Ubuntu上でexampleのプロジェクトを動かすとDllNotFoundExeptionが発生しました。
Program.csでライブラリのパスを指定しているようなのですが、それを見る限り正しい場所にライブラリが置かれているように見えるのですが解決できず

##### 開発が止まっている
こちらも２年ほどリポジトリに動きがありません。

### libsoundio-sharp

https://github.com/atsushieno/libsoundio-sharp

バックエンドにlibsoundioというCライブラリのC#ラッパーライブラリです。
Windowsで動かす場合には、実行ファイルと同じ場所にsoundio.dllが必要で、私は別のlibsoundioラッパーのリポジトリからダウンロードして使いました。
https://github.com/crojewsk/SoundIOSharp/blob/master/SoundIOSharp/libs/soundio.dll

exampleのsio-sineで動作確認をしたところ、<b>WindowsとUbuntu双方で音を出すことに成功しました！</b>

ただ前述した２つと比べると低レベルな記述が必要になり、難易度は高そうです。

### NextAudio

https://github.com/NextAudio/NextAudio

試してないです。

### MiniaudioSharp

https://github.com/Starpelly/MiniaudioSharp

これも試してないです。
MiniaudioというCライブラリのラッパーのようです。

### OpenTK

https://github.com/opentk/opentk

著名なOpenGLのC#ラッパーですが、OpenALを使った音声再生もできるようです。
試していません。


# で結局お前はどうするんだよ
マルチプラットフォーム対応諦めようかなあ

もしほかにもこういうのあるよであったり、私ならこうするであったりがあれば教えていただければ幸いです。