2017-04-02 86 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