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

时间:2016-04-15 05:29:53

标签: ios xcode swift

我试图让我的iphone播放曲调,而不使用预先录制的文件。我有什么选择? AVAudioEngine,AudioKit?我已经看过他们了,但是对于我希望很容易的事情,学习曲线相对陡峭。在PCM缓冲窗口中,它们看起来也像是创建声音效果的工具。

我希望能够做类似

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

首选听起来像仪器或至少不像纯正弦波。

1 个答案:

答案 0 :(得分:0)

编辑:以下代码已被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来播放它们。