播放声音文件并应用音高 - Xcode 8 - Mac

时间:2017-04-02 00:14:08

标签: xcode macos avfoundation

我正在尝试为Mac制作播放声音文件并改变音高的程序。 我发现以下帖子有很多帮助: Xcode 8 Swift 3 Pitch-altering sounds

这是我到目前为止的地方:

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
    }
 }

但是,哈拉斯,它不起作用。它构建正常,但在推动启动时,我收到以下错误: 2017-04-02 01:39:44.254866 AVAudioEngine [5508:159993] [central] 54:错误:> avae> AVAudioEngine.mm:283:AttanetNode:必需条件为false:!nodeimpl-> HasEngineImpl() 2017-04-02 01:39:44.255148 AVAudioEngine [5508:159993] [一般]必需条件为假:!nodeimpl-> HasEngineImpl()

如果有人能帮助我,我会很感激。

1 个答案:

答案 0 :(得分:1)

以下代码正常运行。它正在播放通过“路径”变量定义的文件,并允许实时将音高从440 Hz diapason更改为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