Попытка собрать игровой musi c player (NSF, SP C et c) для Ma c, используя библиотеку GME .
У меня есть потратил часы на часы, тестируя здесь так много решений и советов по SO, но, похоже, ни одно решение не работает хорошо. Я пробовал много вариантов маршрута AVAudioEngine/AVAudioPlayerNode/scheduleBuffer
, но поскольку ни один из них не работал, я просто переключился на преобразование сэмплов в данные Wav и воспроизведение из памяти. Это ДЕЙСТВИТЕЛЬНО работает, однако преобразование из [Int16]
в [UInt8]
(для создания данных для волнового массива) происходит очень медленно. По крайней мере, для более высоких частот дискретизации и песен продолжительностью более нескольких секунд. Пример "чистого" кода ниже. Отзывы и предложения ОЧЕНЬ приветствуются.
Протестировано:
- Пример AVAudioPlayerNode (не удается приступить к работе, например, устройство ввода не найдено, нет звука и т. Д. c et c)
- Пример буфера для данных wav (работает, но медленно)
override func viewDidLoad() {
super.viewDidLoad()
gme_type_list()
var emu = gme_new_emu( gme_nsf_type, 48000 ) // 48kHz
gme_open_file("path-to-file-on-disk.nsf", &emu, 48000) // 48kHz
let sampleCount: Int32 = 150 * 48000 * 2 // 150 = Lenght in sec, 48kHz
var output = Array<Int16>.init(repeating: 0, count: sampleCount)
gme_start_track(emu, 0)
gme_play(emu, sampleCount, &output) // Generates *sampleCount* samples in Int16 format
let samples = output.withUnsafeBufferPointer { buffer -> Array<Int16> 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 "fillWave" method is soooo slow!
play(samples: samples)
}