ios - 如何让 iOS 设备以编程方式播放音乐?

标签 ios xcode swift

我正在尝试让我的 iPhone 在不使用预先录制的文件的情况下播放歌曲。我在这里有什么选择? AVAudioEngine、AudioKit?我已经看过它们,但对于我希望很简单的东西来说,学习曲线相对陡峭。它们看起来也像是在给定 PCM 缓冲区窗口的情况下创建音效的工具。

我希望能够做类似的事情

pitchCreator.play(["C4", "E4", "G4"], durations: [1, 1, 1])

最好听起来像乐器,或者至少不像纯正弦波。

最佳答案

编辑:以下代码已替换为 AudioKit

对于任何想知道这个问题的人;我确实使用类似于下面的代码使其工作(某种程度上)。

class PitchCreator {
  var engine: AVAudioEngine
  var player: AVAudioPlayerNode
  var mixer: AVAudioMixerNode
  var buffer: AVAudioPCMBuffer

  init() {
    engine = AVAudioEngine()
    player = AVAudioPlayerNode()
    mixer = engine.mainMixerNode;
    buffer = AVAudioPCMBuffer(PCMFormat: player.outputFormatForBus(0), frameCapacity: 100)
    buffer.frameLength = 4096
    engine.attachNode(player)
    engine.connect(player, to: mixer, format: player.outputFormatForBus(0))
  }

  func play(frequency: Float) {
    let signal = self.createSignal(frequency, amplitudes: [1.0, 0.5, 0.3, 0.1], bufferSize: Int(buffer.frameLength), sampleRate: Float(mixer.outputFormatForBus(0).sampleRate))
    for i in 0 ..< signal.count {
      buffer.floatChannelData.memory[i] = 0.5 * signal[i]
    }
    do {
      try engine.start()
      player.play()
      player.scheduleBuffer(buffer, atTime: nil, options: .Loops, completionHandler: nil)
    } catch {}
  }

  func stop() {
    engine.stop()
    player.stop()
  }

  func createSignal(frequency: Float, amplitudes: [Float], bufferSize: Int, sampleRate: Float) -> [Float] {
    let π = Float(M_PI)
    let T = sampleRate / frequency
    var x = [Float](count: bufferSize, repeatedValue: 0.0)
    for k in 0 ..< x.count {
      for h in 0 ..< amplitudes.count {
        x[k] += amplitudes[h] * sin(2.0 * π * Float(h + 1) * Float(k) / T)
      }
    }
    return x
  }
}

但它听起来不够好,所以我对我需要的音符进行采样,然后使用 AVAudioPlayer 来播放它们。

关于ios - 如何让 iOS 设备以编程方式播放音乐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36638900/

相关文章:

iphone - 链接器命令失败,PubNub 库在 swift 和静态框架中

ios - 如何使 UITests-Runner 能够访问隐私敏感数据

ios - 使用 Swift 5 - PDFKit 在 iOS 中编辑和保存现有的 pdf 文档

swift - Firebase-Swift 如何将子值相加

ios - 添加 subview 时预期出现声明错误

iOS:MPMoviePlayerController 完成按钮不起作用

ios - 以编程方式更新 info.plist 中的值

ios - 无法将类型 '[String]' 的值转换为预期的参数类型 'String' : while appending arrays to get data from Fireabse in table view cell

objective-c - QTKit,打开输入设备?

inheritance - Swift 语言中的抽象类