・やりたいこと
Sliderの値を変えながら常に再生しているSin波の周波数を変更したい。
トーンジェネレーターのアプリのようにスライドさせながらSin波を変更し、再生したいです。
・現在できていること
再生ボタンを押した際に playSineWave()関数が呼ばれて生成したSin波が再生される
この状態だと、Sliderの値を変更しても再生ボタンを押す前のSliderの値(周波数)が再生されたままです。
アドバイスいただけると嬉しいです。宜しくお願いいたします。
lang
//一部省略しています // エンジンの生成 var audioEngine: AVAudioEngine! // ソースノードの生成 var player: AVAudioPlayerNode! @IBOutlet weak var frequencySlider: UISlider! @IBOutlet weak var frequencyLabel: UILabel! @IBOutlet weak var playButton: UIButton! func playSineWave() { audioEngine = AVAudioEngine() player = AVAudioPlayerNode() // プレイヤーノードからオーディオフォーマットを取得 let audioFormat = player.outputFormat(forBus: 0) // サンプリング周波数: 44.1K Hz let sampleRate = Float(audioFormat.sampleRate) // フレームの長さ let length = sampleRate print("フレームの長さ:\(length)") // PCMバッファーを生成 let buffer1 = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity:UInt32(length)) // frameLength を設定することで mDataByteSize が更新される buffer1.frameLength = UInt32(length) // オーディオのチャンネル数 let channels = Int(audioFormat.channelCount) print("チャンネル数:\(channels)") for ch in (0..<channels) { let samples = buffer1.floatChannelData?[ch] for n in 0..<Int(buffer1.frameLength) { //スライダーの値を周波数としている samples?[n] = sinf(Float(2.0 * M_PI) * frequencySlider.value * Float(n) / sampleRate) } } // オーディオエンジンにプレイヤーをアタッチ audioEngine.attach(player) let mixer = audioEngine.mainMixerNode // プレイヤーノードとミキサーノードを接続 audioEngine.connect(player, to: mixer, format: audioFormat) // 再生の開始を設定 /*player.scheduleBuffer(buffer) { print("Play completed") }*/ do { // エンジンを開始 try audioEngine.start() // 再生 player.play() player.scheduleBuffer(buffer1, at: nil, options: .loops, completionHandler: nil) } catch let error { print(error) } } @IBAction func PlayButton(_ sender: UIButton) { if sender.titleLabel?.text == "Play" { playSineWave() playButton.setTitle("Stop", for: .normal) }else{ player.stop() playButton.setTitle("Play", for: .normal) } }
まだ回答がついていません
会員登録して回答してみよう