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

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

ただいまの
回答率

91.33%

  • Swift

    5071questions

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

  • iOS

    2966questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • iPhone

    741questions

    iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

swiftで一定以上の音量レベルを検知したら画像を表示するコードについて

解決済

回答 1

投稿 2017/11/29 14:43

  • 評価
  • クリップ 0
  • VIEW 48

konhyo1

score 3

録音レベルの値が5.0以上なら画像(contents01)を表示するプログラムを調べながら作ったのですが、うまくいきません。エラーが出ないためどこが間違っているのかわからないのですがどなたか教えていただけるとありがたいです。

今現在実機でデバックしたところ真っ白な画面がでたまま何も起きません。パソコンで実行すると録音レベルの値は表示されているので音声は認識できていると思います。

以下はコード全体です

//
//  ViewController.swift
//

import UIKit
import AVFoundation
import AudioToolbox

private func AudioQueueInputCallback(
    inUserData: UnsafeMutableRawPointer?,
    inAQ: AudioQueueRef,
    inBuffer: AudioQueueBufferRef,
    inSrartTime: UnsafePointer<AudioTimeStamp>,
    inNumberPacketDescriptions: UInt32,
    inPacketDescs: UnsafePointer<AudioStreamPacketDescription>?) {
}

class ViewController: UIViewController {
    @IBOutlet weak var imageView: UIImageView!

    // 音声入力用のキューと監視用タイマーの準備
    var queue: AudioQueueRef!
    var recordingTimer: Timer!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 録音レベルの検知を開始する
        self.startUpdatingVolume()
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        // 録音レベルの検知を停止する
        self.stopUpdatingVolume()
    }

    // 以下の処理を実行したいタイミングでタイマーをスタートさせるだけで録音レベルが検知できる

    // MARK: - 録音レベルを取得する処理
    func startUpdatingVolume() {
        // 録音データを記録するフォーマットを決定
        var dataFormat = AudioStreamBasicDescription(
            mSampleRate: 44100.0,
            mFormatID: kAudioFormatLinearPCM,
            mFormatFlags: AudioFormatFlags(kLinearPCMFormatFlagIsBigEndian |
                kLinearPCMFormatFlagIsSignedInteger |
                kLinearPCMFormatFlagIsPacked),
            mBytesPerPacket: 2,
            mFramesPerPacket: 1,
            mBytesPerFrame: 2,
            mChannelsPerFrame: 1,
            mBitsPerChannel: 16,
            mReserved: 0
        )
        // オーディオキューのデータ型を定義
        var audioQueue: AudioQueueRef? = nil
        // エラーハンドリング
        var error = noErr
        // エラーハンドリング
        error = AudioQueueNewInput(
            &dataFormat,
            AudioQueueInputCallback,
            UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()),
            .none,
            .none,
            0,
            &audioQueue
        )
        if error == noErr {
            self.queue = audioQueue
        }
        AudioQueueStart(self.queue, nil)

        var enabledLevelMeter: UInt32 = 1
        AudioQueueSetProperty(
            self.queue,
            kAudioQueueProperty_EnableLevelMetering,
            &enabledLevelMeter,
            UInt32(MemoryLayout<UInt32>.size)
        )

        self.recordingTimer = Timer.scheduledTimer(
            timeInterval: 1 / 30,
            target: self,
            selector: #selector(self.detectVolume(timer:)),
            userInfo: nil,
            repeats: true
        )
        self.recordingTimer?.fire()
    }

    // 録音レベル検知処理を停止
    func stopUpdatingVolume() {
        // Finish observation
        self.recordingTimer.invalidate()
        self.recordingTimer = nil
        AudioQueueFlush(self.queue)
        AudioQueueStop(self.queue, false)
        AudioQueueDispose(self.queue, true)
    }
    var levelMeter = AudioQueueLevelMeterState()
    @objc func detectVolume(timer: Timer) {
        var propertySize = UInt32(MemoryLayout<AudioQueueLevelMeterState>.size)

        AudioQueueGetProperty(
            self.queue,
            kAudioQueueProperty_CurrentLevelMeterDB,
            &levelMeter,
            &propertySize)

       print(levelMeter.mPeakPower)

                func setLabelText () {
                    if levelMeter.mPeakPower > 5.0 {
            let image = UIImage(named: "contents01")
                        imageView.image = image

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • fuzzball

    2017/11/29 16:12

    「録音レベルが5以上にならない」のか、「録音レベルは5以上になるけど画像が表示されない」のか、どちらでしょうか?

    キャンセル

  • konhyo1

    2017/11/29 16:13

    「録音レベルは5以上になるけど画像が表示されない」状態です

    キャンセル

  • fuzzball

    2017/11/29 16:22

    質問内のコードでは、画像をセットしている setLabelText() が呼ばれていないようですが、どこからか呼んでいますか?

    キャンセル

回答 1

checkベストアンサー

+1

func setLabelText () {
    if levelMeter.mPeakPower > 5.0 {
        let image = UIImage(named: "contents01")
        imageView.image = image
    }
}

の、関数定義部分を削除して、

if levelMeter.mPeakPower > 5.0 {
    let image = UIImage(named: "contents01")
    imageView.image = image
}

でどうでしょうか?

投稿 2017/11/29 16:24

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/11/29 16:32

    ご回答いただきありがとうございます。無事に解決いたしました。この問題で長い間悩んでいたので実行できて良かったです。本当にありがとうございます!!

    キャンセル

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

ただいまの回答率

91.33%

関連した質問

同じタグがついた質問を見る

  • Swift

    5071questions

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

  • iOS

    2966questions

    iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

  • iPhone

    741questions

    iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。