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

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

ただいまの
回答率

91.37%

  • Swift

    5024questions

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

  • iOS

    2953questions

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

  • Xcode

    2849questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

  • iPhone

    738questions

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

swiftで一定以上の音量レベルを検知したらmp3を再生するコードについて

解決済

回答 1

投稿 2017/11/26 19:33

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

konhyo1

score 3

大学の自主制作グループ課題でタイトルのような機能を持ち合わせたiOSアプリを作ろうとしているのですが、エラーがたくさん出てしまい困っています。どなたか教えてくださると幸いです。
エラーは以下のとおりです。

(l25)
sound.data // → Data型、音データが入っている
エラーメッセージ
Expected declaration

(l41)
override func viewDidLoad() {
エラーメッセージ
'viewDidLoad()' has already been overridden

(l128)
self.statusImage.isHidden = (levelMeter.mPeakPower >= -1.0) ? false : true
エラーメッセージ
Value of type 'ViewController' has no member 'statusImage'

全体のコードは以下の通りです。

//
//  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 {

    let sound = NSDataAsset(name: "imazinnza0")
    sound.data // → Data型、音データが入っている

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

        // 音声入力用のキューと監視用タイマーの準備
        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)

            // 取得した録音レベルに応じてimageを切り替える
            self.statusImage.isHidden = (levelMeter.mPeakPower >= -1.0) ? false : true
            print(levelMeter.mPeakPower)
        }

        // 録音レベルの値によってmp3ファイル”imazinzza0”を鳴らす
        func setLabelText () {
            if levelMeter.mPeakPower > -40.0 {

                class ViewController: UIViewController {
                    var player: AVAudioPlayer?

                    func tapBtn() {
                        if let sound = NSDataAsset(name: "imazinnza0") {
                            player = try? AVAudioPlayer(data: sound.data)
                            player?.play() // → これで音が鳴る
                        }
                    }
                }

        }
    }
}


よろしくお願いします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

+1

(l25)
sound.data // → Data型、音データが入っている
エラーメッセージ
Expected declaration

エラーメッセージをWebで検索するとすぐにヒットすると思いますが、クラスに直接処理を書こうとしているからだと思われます。
そもそも sound.data だけの行に意味はないと考えます。

(l41)
override func viewDidLoad() {
エラーメッセージ
'viewDidLoad()' has already been overridden

エラーメッセージ通りです。
viewDidLoadが2回宣言されています。

(l128)
self.statusImage.isHidden = (levelMeter.mPeakPower >= -1.0) ? false : true
エラーメッセージ
Value of type 'ViewController' has no member 'statusImage'

エラーメッセージ通りです。
statusImageがViewControllerのメンバ変数として宣言されていません。

投稿 2017/11/26 20:18

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/26 20:48

    エラーメッセージとアドバイスをもとに試行錯誤してみたらなんとかできました!ありがとうございます!

    キャンセル

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

ただいまの回答率

91.37%

関連した質問

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

  • Swift

    5024questions

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

  • iOS

    2953questions

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

  • Xcode

    2849questions

    Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

  • iPhone

    738questions

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