title: How to play an array of [Int16] audio samples from memory in Swift
body: <p>Trying to build a game music player (NSF, SPC etc) for Mac, using the <a href="https://bitbucket.org/mpyne/game-music-emu/wiki/Home" rel="nofollow noreferrer">GME</a> library.</p>
  <p>I have spent hours upon hours testing so many solutions and tips here on SO, but it seems no solution works well. I have tried many variants of the <code>AVAudioEngine/AVAudioPlayerNode/scheduleBuffer</code> route, but since none of them worked I simply switched to converting the samples to Wav data and playing from memory. That DOES work, however, converting from <code>[Int16]</code> to <code>[UInt8]</code> (in order to create data for a wave array) is very slow. At least for higher sample rates and songs longer than a few seconds. &quot;Clean&quot; code example below. Feedback and suggestions VERY welcome.</p>
  <p>Tested:</p>
  <ol>
  <li><a href="https://stackoverflow.com/questions/60641585/schedule-buffer-with-avaudiopcmbuffer-int16-data">AVAudioPlayerNode example</a> (cannot get to work, eg. input device not found, no sound etc etc)</li>
  <li><a href="https://gist.github.com/hotpaw2/4eb1ca16c138178113816e78b14dde8b" rel="nofollow noreferrer">Buffer to wav data example</a> (works, but sloooow)</li>
  </ol>
  <hr />
  <pre><code>override func viewDidLoad() {
      super.viewDidLoad()
  
      gme_type_list()
  
      var emu = gme_new_emu( gme_nsf_type, 48000 ) // 48kHz
      gme_open_file(&quot;path-to-file-on-disk.nsf&quot;, &amp;emu, 48000) // 48kHz
  
      let sampleCount: Int32 = 150 * 48000 * 2 // 150 = Lenght in sec, 48kHz
      var output = Array&lt;Int16&gt;.init(repeating: 0, count: sampleCount)
  
      gme_start_track(emu, 0)
      gme_play(emu, sampleCount, &amp;output) // Generates *sampleCount* samples in Int16 format
  
      let samples = output.withUnsafeBufferPointer { buffer -&gt; Array&lt;Int16&gt; in
          var result = [Int16]()
          for i in stride(from: buffer.startIndex, to: buffer.endIndex, by: 2) {
              result.append(buffer[i])
          }
          return result
      }
  
      // Calls a slightly modified version of example 2 above 
      // (to support own samples, in Int16 rather than Float).
      // Works! But &quot;fillWave&quot; method is soooo slow!
      play(samples: samples)
  }
  </code></pre>