「Xamarin.Mac/効果音を再生する」の版間の差分
73行目: | 73行目: | ||
} | } | ||
</source> | </source> | ||
+ | |||
+ | ==連射音== | ||
+ | AVAudioPlayerでは1インスタンス1音の再生となる。 | ||
+ | 複数のスレッドから一斉にPlayメソッドを叩いた場合は最初の再生が終わるまで全部無効となる。 | ||
+ | |||
+ | そのような場合は高速化など糞食らえで複数のインスタンスを生成する。 | ||
+ | <source lang="csharp"> | ||
+ | public override void MouseDown(NSEvent theEvent) | ||
+ | { | ||
+ | Task.Run(() => { | ||
+ | var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources"); | ||
+ | var file = Path.Combine(path,"se001.caf"); | ||
+ | var url = new NSUrl(file, isDir: false); | ||
+ | |||
+ | var player = AVAudioPlayer.FromUrl(url); | ||
+ | player.Play(); | ||
+ | }); | ||
+ | Console.WriteLine("click"); | ||
+ | } | ||
+ | </source> | ||
+ | 注意点としては複数インスタンスでの同時再生はcafファイル(Apple CoreAudio フォーマット)に限られ、mp3ファイルなどは使用できない。 | ||
+ | mp3ファイルなどからcafファイルへの変換はMac上のターミナルから[[afconvertコマンド]]でできる。 | ||
==関連項目== | ==関連項目== |
2015年9月30日 (水) 14:30時点における最新版
Xamarin.Macで効果音を再生したい。
目次
NSSoundを使う[編集 | ソースを編集]
NSSoundを使うと簡単に効果音を再生できる。
var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources");
var file = Path.Combine(path,"se001.mp3");
var sound = new NSSound(file, byRef:false);
sound.Play();
利点[編集 | ソースを編集]
MonoMacからXamarin.MacやXamarin.iOSまでアップル系プラットフォームであれば新旧を問わず幅広く利用できる。
欠点[編集 | ソースを編集]
NSSoundはメインスレッドでしか使用できないという欠点を抱えている。 しかも画像系APIと異なり、メインスレッド以外で実行しても効果音の再生がされないだけでエラーにはならない。
これに気がつかずバグったときのデバッグで苦しむことになるかもしれない。
AVFoundationのAVAudioPlayerを使う[編集 | ソースを編集]
AVAudioPlayerを使用しても簡単に効果音を再生できる。 現状ではベストな方法ではないかと思われる。
var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources");
var file = Path.Combine(path,"se001.mp3");
var url = new NSUrl(file, isDir: false);
var player = AVAudioPlayer.FromUrl(url);
player.PrepareToPlay();
player.Play();
利点[編集 | ソースを編集]
AVAudioPlayerはアプリ外部の音声関連サービスに再生を依頼する方式であるため、メインスレッドでなくても問題なく使用できるという利点がある。 このため再生処理を以下のようにスレッドプールに逃がすことでメインスレッドが占有されることもなくなる。
Task.Run( () => player.Play() );
また、PrepareToPlayメソッドで即時再生用にメモリに先読みしておくこともできるため初回再生が若干遅いということもない。
欠点[編集 | ソースを編集]
AVFoundationということで同APIのサポートが(実用レベルで)追加されたXamarin.Macの2015年中頃のバージョン以降に限定される。古いXamarin.Macを購入しバージョンアップしていない人やMonoMacの人は残念賞なようだ。なお、Xamarin.iOSもこの方法を利用できる。
共通[編集 | ソースを編集]
再生開始までのタイムラグを無くすため、音声再生に関するクラスインスタンスの生成はウインドウ初期化時(AwakeFromNibメソッド)などで行い、フィールド変数として保持しておくことが望ましい。
AVAudioPlayer _player;
public override void AwakeFromNib()
{
base.AwakeFromNib();
var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources");
var file = Path.Combine(path,"se-033a.mp3");
var url = new NSUrl(file, isDir: false);
_player = AVAudioPlayer.FromUrl(url);
_player.PrepareToPlay();
}
public override void MouseDown(NSEvent theEvent)
{
Task.Run(() => _player.Play());
}
連射音[編集 | ソースを編集]
AVAudioPlayerでは1インスタンス1音の再生となる。 複数のスレッドから一斉にPlayメソッドを叩いた場合は最初の再生が終わるまで全部無効となる。
そのような場合は高速化など糞食らえで複数のインスタンスを生成する。
public override void MouseDown(NSEvent theEvent)
{
Task.Run(() => {
var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources");
var file = Path.Combine(path,"se001.caf");
var url = new NSUrl(file, isDir: false);
var player = AVAudioPlayer.FromUrl(url);
player.Play();
});
Console.WriteLine("click");
}
注意点としては複数インスタンスでの同時再生はcafファイル(Apple CoreAudio フォーマット)に限られ、mp3ファイルなどは使用できない。 mp3ファイルなどからcafファイルへの変換はMac上のターミナルからafconvertコマンドでできる。
関連項目[編集 | ソースを編集]
- MonoMac/AppleScriptを実行する
- MonoMacにはNSAppleScriptクラスが存在しないため別の手段を使う必要がある。