2017-12-16 18 views
1

angewandt Mit AVFoundation und AVAudioPlayerNode Ton spielt mit Xcode Version 9.2 (9C40b) und Bereitstellung von iOS 11.2AVAudioPlayerNode Volumenänderung wird nicht sofort

Das Problem, dass, wenn Sie die Lautstärke ändern, wird die Änderung nicht das erste Mal angewandt Sie spielen den Sound, und es gibt andere seltsame Effekte.

Starten Sie ein neues Projekt in Xcode, wählen iOS Spiel, und geben Sie einen beliebigen Namen. Dann ersetzen Sie den Code in GameScene.swift mit:

import SpriteKit 
import GameplayKit 
import AVFoundation 

class GameScene: SKScene { 

    var entities = [GKEntity]() 
    var graphs = [String : GKGraph]() 

    let audioFilePlayer = AVAudioPlayerNode() 
    var audioFile:AVAudioFile! = nil 
    var audioFileBuffer:AVAudioPCMBuffer! = nil 

    override func sceneDidLoad() { 
     do { 
      let path = Bundle.main.path(forResource: "sound", ofType: "caf")! 
      let url = URL(fileURLWithPath: path) 
      audioFile = try AVAudioFile(forReading: url) 
      audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFile.processingFormat, frameCapacity: UInt32(audioFile.length)) 
      try audioFile.read(into: audioFileBuffer!) 
      audioEngine.attach(audioFilePlayer) 
      audioEngine.connect(audioFilePlayer, to: audioEngine.mainMixerNode, format: audioFileBuffer?.format) 
      try audioEngine.start() 
     } 
     catch { 
      print(error) 
     } 

     let playAction = SKAction.sequence([ 
      SKAction.wait(forDuration: 3.0), 
      SKAction.run { self.play(volume: 1.0) }, 
      SKAction.wait(forDuration: 1.0), 
      SKAction.run { self.play(volume: 1.0) }, 
      SKAction.wait(forDuration: 1.0), 
      SKAction.run { self.play(volume: 0.0) }, 
      SKAction.wait(forDuration: 1.0), 
      SKAction.run { self.play(volume: 0.0) }, 
      SKAction.wait(forDuration: 1.0), 
      SKAction.run { self.play(volume: 1.0) }, 
      SKAction.wait(forDuration: 1.0), 
      SKAction.run { self.play(volume: 1.0) }, 
      ]) 
     self.run(playAction) 

    } 

    func play(volume:Float) { 
     print("playing at \(volume)") 
     audioFilePlayer.stop() 
     audioFilePlayer.volume = volume 
     audioFilePlayer.scheduleFile(audioFile, at: nil, completionHandler: nil) 
     audioFilePlayer.play() 
    } 

} 

Apologies für arme optionals ... Auch eine Sounddatei sound.caf zum Projekt mit dem Namen hinzuzufügen.

Console Ausgabe lautet:

playing at 1.0 
playing at 1.0 
playing at 0.0 
playing at 0.0 
playing at 1.0 
playing at 1.0 

Ich würde erwarten, zu hören: laut, laut, nichts, nichts, laut, laut.

Ich höre tatsächlich: laut, laut, laut, nichts, weich, laut

(die 'weiche' ist besonders seltsam)

ich auch mit dem Master-Volume versucht haben, zu ändern:

audioEngine.mainMixerNode.outputVolume = volume 

aber die Sounds sind die gleichen.

In älteren Spielen, verwendet, um OpenAL zu verwenden, aber dies erfordert Obj-C und ist ziemlich chaotisch mit Bridging-Header usw. Auch OpenAL wird angeblich nicht mehr unterstützt. SKAction-basiertes Audio kann nicht viele Sounds verarbeiten, die sich schnell ohne Pannen und Kratzer wiederholen (es ist ein Weltraum-Shooter-Spiel ...) Das Problem ist im Simulator und auf dem Gerät dasselbe. Jede Hilfe wird geschätzt!

Antwort

1

OK Ich fand die Antwort. Audioengine muss nach Volumenänderungen zurückgesetzt werden, damit die Änderungen sofort sein:

audioEngine.reset() 

diese Funktion play() funktioniert:

func play(volume:Float) { 
     print("playing at \(volume)") 
     audioFilePlayer.volume = volume 
     audioEngine.reset() 
     audioFilePlayer.stop() 
     audioFilePlayer.scheduleFile(audioFile, at: nil, completionHandler: nil) 
     audioFilePlayer.play() 
    } 
Verwandte Themen