低遅延でオーディオを処理する場合 (これはリアルタイムで使用されるすべてのソフトシンセの絶対要件です)、オーディオ レンダリングに別のスレッドを使用することが必須であり、さらに、リアルタイム スケジューリングの優先度が必要です。これを UI コードに渡したくないのは確かです。
オーディオは頻繁に修理する必要があります。おそらくミリ秒に 1 回です。UI スレッドは他のタスクで忙しく、UI イベントをディスパッチしている間はオーディオを処理できません。システムが達成できるレイテンシーは、オーディオ バッファーを満たすための最長のスケジューリング レイテンシーによって制限されます。これは、UI スレッドで無制限になる可能性があります。
オーディオ IO にアクセスするためにどのライブラリを使用しているか、または実際にどのプラットフォームで使用しているかは明確ではありません。QAudioOutput
QtMultimedia が提供するものは、ここで必要なものではないようです。
ほとんどの場合、オーディオ レンダー コールバックは、Qt とのやり取りがほとんどない状態で発生します。レンダー リクエストを UI スレッドにポストしたくないのは確かです。これは、QT 開発の自然なパラダイムのように思えるかもしれません。
プラットフォームのオーディオ ライブラリの設定方法に応じて、次のようになります。
- リアルタイム スレッドを作成し、バッファがいっぱいになるまでブロックします (Linux/Alsa)。また、
- オーディオ ライブラリがこれを行い、コールバックします (MacOSX & iOS/CoreAudio)。
レンダー スレッドでは、do は、出力バッファーを満たすデータを生成する以外に何もしないでください。また、ブロックする可能性のある操作を実行しません。
少し毛むくじゃらのビットは、レンダー ループにノート データを取得するスレッド セーフです。イベントキューにアクセスする際の優先順位の逆転を避けるために、これは通常ロックレス FIFO として実装されます。レンダー スレッド内から UI の更新をトリガーする場合は、これらを UI ループにポストする必要があります。これには、Qt のシグナルとスロットが適しています。
プロジェクトの真の目的がソフト シンセの開発である場合は、 VSTプラグインを開発したほうがよいかもしれません。スレッド化の問題を処理するオープン ソースの VST ホストは多数あります。
また、VST ホストとプラグインのソース コードを提供するJuceも検討してみてください。