2017-04-02 92 views
0

我正在試圖製作播放聲音文件並更改音高的Mac程序。 我發現下面的帖子裏面有很大幫助: Xcode 8 Swift 3 Pitch-altering sounds播放聲音文件並應用音調 - Xcode 8 - Mac

這裏是我到目前爲止:

import Cocoa 
import AVFoundation 

let engine = AVAudioEngine() 
let audioPlayerNode = AVAudioPlayerNode() 
let changeAudioUnitTime = AVAudioUnitTimePitch() 
var file = AVAudioFile() 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate { 

    @IBOutlet weak var window: NSWindow! 
    func applicationDidFinishLaunching(_ aNotification: Notification) 
    {do 
     { 
      if let audioFileURL = Bundle.main.url(forResource: "/Volumes/.../file", withExtension: "m4v") 
      { 
       file = try AVAudioFile(forReading: audioFileURL) 
       audioPlayerNode.scheduleFile(file, at: nil, completionHandler: nil) // File is an AVAudioFile defined previously 
      } 
     }catch let error as NSError { 
      print(error.localizedDescription) 
     } 


    } 

    func setupAudioEngine() 
    { 
     engine.attach(audioPlayerNode) 
     engine.attach(changeAudioUnitTime) 
     engine.connect(audioPlayerNode, to: changeAudioUnitTime, format: nil) 
     engine.connect(changeAudioUnitTime, to: engine.outputNode, format: nil) 
     try? engine.start() 
     audioPlayerNode.play() 
    } 

    func hitSound(value: Float) 
    { 
     changeAudioUnitTime.pitch = value 
    } 

    @IBAction func lanch(_ sender: NSButton) 
    { 
     setupAudioEngine() 
     hitSound(value: 0) 
    } 

    @IBAction func stop(_ sender: NSButton) 
    { 
     exit(0) 
    } 

    func applicationWillTerminate(_ aNotification: Notification) { 
     // Insert code here to tear down your application 
    } 
} 

但是,hallas,這是行不通的。它建立好,但推動啓動時,我得到以下錯誤: 2017-04-02 01:39:44.254866 AVAudioEngine [5508:159993] [中央] 54:錯誤:> avae> AVAudioEngine.mm:283:AttachNode:要求的條件是假的!nodeimpl-> HasEngineImpl() 2017年4月2日01:39:44.255148 AVAudioEngine [5508:159993] [常規]要求的條件是假的!nodeimpl-> HasEngineImpl()

如果有人可以幫助我,我會感激。

+0

此行似乎不正確:audioPlayerNode.scheduleFile(文件,網址爲:無,completionHandler:無)。它有時會使應用程序崩潰。 – Fredo

+0

有了這段代碼,它正在播放文件,但仍然沒有應用音高。在applicationDidFinishLaunching(_ aNotification:通知) { 令路徑= 「/Volumes/.../Musique/Hind/Musique indienne.m4a」 讓URL = URL(fileURLWithPath:路徑) 做 { AUDIOFILE =嘗試AVAudioFile (forReading:url,commonFormat:AVAudioCommonFormat.pcmFormatInt16,interleaved:false) } catch let error as NSError {print(error.localizedDescription)} } – Fredo

回答

1

以下代碼正在工作。它正在播放通過「路徑」變量定義的文件,並允許實時將音高從440 Hz直徑變爲432 Hz(詳情參見柏拉圖的比例尺),只需單擊複選框即可。我添加了一個界面圖片來幫助創建它。

import Cocoa 
import AVFoundation 

let engine = AVAudioEngine() 
let audioPlayerNode = AVAudioPlayerNode() 
var changeAudioUnitTime = AVAudioUnitTimePitch() 
var audioFile = AVAudioFile() 

@NSApplicationMain 
class AppDelegate: NSObject, NSApplicationDelegate 
{ 

    @IBOutlet weak var window: NSWindow! 

    @IBOutlet weak var change432: NSButton! 

    func applicationDidFinishLaunching(_ aNotification: Notification) 
    { 
    } 


    func setupAudioEngine() 
    { 
     let path = "/Volumes/.../Musique/Musique indienne.m4a" 
     let url = URL(fileURLWithPath: path) 

     do 
     { 
      audioFile = try AVAudioFile(forReading: url, commonFormat: AVAudioCommonFormat.pcmFormatInt16, interleaved: false) 
     } 
     catch let error as NSError {print(error.localizedDescription)} 

     engine.attach(audioPlayerNode) 
     engine.attach(changeAudioUnitTime) 
     engine.connect(audioPlayerNode, to: changeAudioUnitTime, format: nil) 
     engine.connect(changeAudioUnitTime, to: engine.outputNode, format: nil) 

     audioPlayerNode.scheduleFile(audioFile, at: nil, completionHandler: nil) 

     try? engine.start() 
     audioPlayerNode.play() 
    } 

    @IBAction func changeDiapason(_ sender: NSButton) 
    { 
     if change432.state == NSOnState 
     { 
      changeAudioUnitTime.pitch = -32 // = 432 Hz(valeurs admises de -2400 à 2400, une octave étant 1200 cents). 
     } 
     if change432.state == NSOffState 
     { 
      changeAudioUnitTime.pitch = 1 
     } 

    } 

    @IBAction func lancer(_ sender: NSButton) 
    { 
     setupAudioEngine() 
    } 

    @IBAction func stopper(_ sender: NSButton) 
    { 
     audioPlayerNode.stop() 
     audioPlayerNode.reset() 
     engine.stop() 
     engine.disconnectNodeInput(changeAudioUnitTime) 
     engine.disconnectNodeInput(audioPlayerNode) 
     engine.detach(changeAudioUnitTime) 
     engine.detach(audioPlayerNode) 
     engine.reset() 
     //exit(0) 
    } 

    func applicationWillTerminate(_ aNotification: Notification) 
    { 
     // Insert code here to tear down your application 
    } 
} 

Interface