質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

1891閲覧

swift3 効果音 引っかかり?

komeo

総合スコア9

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2017/01/21 02:10

iPadのアプリを制作しています。

ドラッグで移動するViewのy座標に合わせて効果音を1回だけ再生したいです。

yが150のときに「雨の音」
yが300のときは「風の音」など

一応出来たんですが・・
効果音が再生されるときにドラッグに引っかかりが出るというか
再生待ち?になるのか、一瞬(というか再生開始まで)止まってしまい
スムーズに動きません。

再生後はまたスムーズに動くという感じになります。
初回の効果音が特にそうなります。

Xcodeのシミュレーターでは問題無く動くのですが
実機テストでは上記のようになりました。

上手く伝わらないかも知れずで恐縮です、、、

以下、コードです。

ちなみに試してみた事として
効果音を用意したときに
ボリューム0で先に再生しておくと多少マシにはなるようではあるのですが、、
完全に無くなるという事でも無いようです

何か重くなるコードを書いてをしてしまっているんでしょうか。

よろしくお願い致します。

OSX 10.11.6
Xcode 8.2.1
Swift 3
テスト実機 iPad Air2 MNV72J/A iOS10.2

Swift3

1import UIKit 2import AVFoundation 3 4class ViewController: UIViewController { 5 6 //ドラッグ用のView 7 var my:UIView = UIView() 8 9 //雨の音 10 var rain:AVAudioPlayer! = nil 11 //雨の音監視用 12 var rainPlay:Bool = true 13 14 //風の音 15 var wind:AVAudioPlayer! = nil 16 //風の音監視用 17 var windPlay:Bool = true 18 19 //ドラッグのy座標監視 タイマーにて 20 var timer:Timer! 21 22 override func viewDidLoad() { 23 super.viewDidLoad() 24 25 //View設置 26 my.frame = CGRect(x:100, y:100, width:200, height:200) 27 my.backgroundColor = UIColor.gray 28 self.view.addSubview(my) 29 30 //効果音用意(雨の音) 31 var url = NSURL.fileURL(withPath: Bundle.main.path(forResource: "rain", ofType: "mp3")!) 32 do{ 33 rain = try AVAudioPlayer(contentsOf: url) 34 }catch{ 35 print("no rain") 36 } 37 rain.prepareToPlay() 38 39 //先にボリューム0で再生してみたテストです 40 //rain.volume = 0 41 //rain.play() 42 //先再生したテストでは多少はましになります。 43 44 //効果音用意(風の音) 45 url = NSURL.fileURL(withPath: Bundle.main.path(forResource: "wind", ofType: "mp3")!) 46 do{ 47 wind = try AVAudioPlayer(contentsOf: url) 48 }catch{ 49 print("no wind") 50 } 51 wind.prepareToPlay() 52 } 53 54 //ドラッグはtouchMovedで 55 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 56 let e = touches.first! 57 let dx = e.location(in:self.view).x - e.previousLocation(in:self.view).x 58 let dy = e.location(in:self.view).y - e.previousLocation(in:self.view).y 59 60 my.frame.origin.x += dx 61 my.frame.origin.y += dy 62 } 63 64 //座標監視はas3で云うenterFrame的なそれで 65 func enterFrame(){ 66 let y = my.frame.origin.y 67 68 //最初の効果音(雨の音) 69 //ここでドラッグが効果音に引っかる?ように一旦止まり、効果音再生後にはまたスムーズにドラッグ操作が出来きます 70 if(y > 150){ 71 if(rainPlay){ 72 rainPlay = false 73 //先再生テスト用 74 //rain.volume = 1 75 rain.play() 76 } 77 }else{rainPlay = true} 78 79 //2番目の効果音(風の音) 80 //初回ほどでは無いですが、やや引っかかりがあったり無かったりです 81 if(y > 300){ 82 if(windPlay){ 83 windPlay = false 84 wind.play() 85 } 86 }else{windPlay = true} 87 88 //以下、、、3番目、4番目と続きます 89 90 } 91 92 override func viewDidAppear(_ animated: Bool) { 93 super.viewDidAppear(true) 94 //タイマー監視 95 timer = Timer.scheduledTimer(timeInterval:0.5,target:self,selector:#selector(self.enterFrame),userInfo:nil,repeats:true) 96 timer.fire() 97 } 98 99 override func viewDidDisappear(_ animated: Bool) { 100 super.viewDidDisappear(true) 101 //タイマー破棄? 102 timer.invalidate() 103 } 104 105 override func didReceiveMemoryWarning() { 106 super.didReceiveMemoryWarning() 107 // Dispose of any resources that can be recreated. 108 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

iPadやSwiftに暗いのですが一般的な問題と捉えた範囲でのコメントをします。

音声の再生が始まるとハードウェアによるバックグラウンド処理により発音されるのですが、ハードウェアを動かすための初期動作に多少時間がかかることはよくあると思います。例えばバッファを確保してそこへ全部あるいは一部の音声データを読み込んだりといったことが考えられます。あらかじめ音量0で鳴らすと現象が軽減されるというのは、初期動作で行ったI/O結果がキャッシュされたためと考えられます。

いずれにせよ音を鳴らすための処理に数10msec~100msecオーダーの時間がかかるとしてそれをUIスレッドで直接行ってしまうとご質問のような影響が出る結果になると思います。

対応としては一般的に以下のような考え方にすると思います。

  • バックグラウンド処理を行うためのスレッドをあらかじめ起動しておく

例えばマウスドラッグで音を鳴らすような画面を開いた時点でスレッドを起動してしまいます。音を鳴らす処理はこのスレッド上で行うようにします。

  • UIスレッドではバックグラウンドスレッドへ簡単な指示(この音を鳴らせなど)のみ行う

どんな言語・ライブラリーでもスレッド間の同期をとるための機能が提供されていると思いますのでそうしたものを使いスレッド間で情報のやりとりを行います。ただ今回のようなものですと厳密なスレッド間同期の必要性は低く、単にUIスレッドから鳴らしたい音が変化した際に大域変数的なものへ音の種類を直接設定し、バックグラウンドスレッドでは100msec前後の間隔でその変数を監視しつつ音を鳴らすといったシンプルな作りでもよい気もします。

投稿2017/01/21 02:54

編集2017/01/21 02:56
KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komeo

2017/01/21 23:27

ご回答ありがとうございます。 勉強になります。急ぎその方向での検証をしてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問