Хотите изменить скорость 3D-пространственного звука с помощью SceneKit - PullRequest
0 голосов
/ 03 октября 2019

-Надеюсь, у всех будет прекрасный день / вечер, где бы вы ни были! :)

Заранее извиняюсь, если этот вопрос не отформатирован / структурирован неправильно. Это моя первая публикация, и не все управляемые режимы доступны с использованием технологии чтения с экрана. Итак, мои извинения.

Я пытаюсь создать небольшую демонстрационную версию 3D-аудио комплекта с изюминкой. Мне нужно включить некоторую обработку звука для пространственного аудио.

IE Мне нужно добавить аудиоустройство Varispeed (или что-то, что может производить аналогичный эффект) к аудио, которое воспроизводится из SCNAudioPlayer, подключенного к SCNNode,Мне нужно только замедлить или ускорить аудио без необходимости компенсации высоты тона.

Я изучал Stack и остальную часть сети Интернет уже более недели в свободное время, пытаясь найти магию, нопока это все еще намекает на меня. :)

Просто для наглядности я проверил:

Как изменить высоту звука во время воспроизведения? (Swift 4)

Присоединение эффектов AudioUnit к узлам SCNAudioSource в SceneKit

- и эти два в надежде, что может быть что-нибудь, что могло бы помочь удаленно…

AVAudioPlayerNode не воспроизводит звук

Изменение громкости SCNAudioPlayer в реальном времени - Swift

- и множество других страницот Stack и других форумов (Apple и т. д.), но, похоже, ни один из примеров не относится непосредственно к моему конкретному сценарию использования.

Были получены отличные ответы, но пока они, похоже, включают создание отдельных экземпляров AVAudioEngine и созданиеграфик вручную. Я хотел бы использовать существующий экземпляр AVAudioEngine, который предоставляет Scene Kit, и просто добавить к нему определенные узлы с обработанным звуком. - И мне просто не ясно, возможно ли это или нет.

Я могу заставить стандартный трехмерный позиционный набор звуковых сцен работать нормально, а также подключить AVAudioPlayerNode к текущему экземпляру AVAudioEngine, созданному в данный момент, и иметьэто обработано с аудиоустройством Varispeed. Однако звук не пространственный.

Я предполагаю, что это потому, что (как в приведенном ниже коде) я подключаю AVAudioPlayerNode к блоку Varispeed, а затем подключаю его к главному узлу микшера двигателя. Тем не менее, я не могу найти других примеров того, как настроить AVAudioPlayerNode для выполнения того, что мне нужно.

Так что, хотя я создаю SCNAudioPlayer из AVAudioPlayerNode (который обрабатывается с помощью varispeed), а затем добавляю этот SCNAudioPlayer вSCNNode, он все равно не будет отображаться в 3D.

Аудио файл воспроизводится нормально и может быть обработан, но не пространственно. Кроме того, как примечание, файл находится в моно, что и требует набор сцены для его пространственного размещения в 3D.

Моя другая мысль состояла в том, чтобы попытаться добавить выходные данные модуля Varispeed кaudioEnvironmentNode движка вместо основного узла микшера движка, но у меня это тоже не сработает. Похоже, что приложение просто зависает, когда я пытаюсь подключить блок Varispeed к ядру audioEnvironmentNode.

Я не получаю от консоли никакой информации о том, что может происходить, и приложение не выдает никаких исключений. Тем не менее, он, по-видимому, просто выполняется до того момента, когда узел Varispeed подключается к audioEnvironmentNode движка, а затем кажется зависшим. -Кто не предлагает мне никакой помощи в решении этого. :) Я пытаюсь проверить, является ли audioEnvironmentNode нулевым, но в любом случае не получаю никакого результата. IE консоль не выводит абсолютно ничего в отношении audioEnvironmentNode. -Похожу на цифру…

Я намерен продолжить это, но на этом этапе мне нужно немного подержать руки. :)

Моей последней мыслью было посмотреть, смогу ли я добавить AVAudioPlayerNode напрямую в SCNNode, но это не представляется возможным.

Наконец,вот мой код ниже. Еще раз прошу прощения за необычное форматирование.

Спасибо, что взглянули на это, и любая помощь или предложения от кого-либо, несомненно, будут оценены! Если я упускаю что-то очень очевидное здесь, пожалуйста, будьте осторожны:) Я осмелюсь сказать, что документы Apple относительно отношений между SceneKit и AVFoundation не являются для меня сверхинтуитивными, по крайней мере…

Спасибо и ура! :)

// Creating an AVAudioPlayerNode with processing via Varispeed
let saucerSoundAudioNode = load(file: "ablue", ofType: "wav")

// Creating an SCNAudioPlayer from the AVAudioPlayerNode
let saucerSoundPlayer = SCNAudioPlayer(avAudioNode: saucerSoundAudioNode)

// Adding the SCNAudioPlayer to an SCNNode
  saucerNode.addAudioPlayer(saucerSoundPlayer)

// this function loads audio data and creates an aVAudioPlayerNode
// It then connects that node to an instance of AVAudioUnitVarispeed
// The Varispeed node is then connected to the engine's main mixer node
// The function then returns the AVAudioPlayerNode
func load(file name: String, ofType type: String) -> AVAudioPlayerNode {

   let audioPlayer = AVAudioPlayerNode()
    audioPlayer.volume = 1.0

    let path = Bundle.main.path(forResource: "art.scnassets/"+name, ofType: type)!
    let url = NSURL.fileURL(withPath: path)

    let file = try? AVAudioFile(forReading: url)

    let buffer = AVAudioPCMBuffer(pcmFormat: file!.processingFormat, frameCapacity: AVAudioFrameCount(file!.length))

    do {
        try file!.read(into: buffer!)
    } catch _ {

print («файл не может быть прочитан в буфер»)

    }

print («файл был прочитан»)

let engine =scnView.audioEngine let pitch = AVAudioUnitVarispeed ()

engine.attach (audioPlayer) engine.attach (шаг)

      engine.connect(audioPlayer, to: pitch, format: file?.processingFormat)

engine.connect (шаг, к: engine.mainMixerNode, формат:file? .processingFormat)

// Замена engine.mainMixerNode на scnView.audioEnvironmentNode, кажется, приводит к зависанию приложения // Консоль не показывает никаких ошибок, но выполнение останавливается

    audioPlayer.scheduleBuffer(buffer!, at: nil, options: AVAudioPlayerNodeBufferOptions.loops, completionHandler: nil)

return audioPlayer

}

1 Ответ

0 голосов
/ 12 октября 2019

Я нашел ответ на свой вопрос, поэтому хотел опубликовать это на тот случай, если у других могут возникнуть такие же или похожие проблемы с этим.

Оказывается, мне нужно было явно установить audioListener как pointOfViewпрежде чем я смог получить доступ к audioEnvironmentNode экземпляра AVAudioEngine, который создается SceneKit.

Кроме того, мне нужно было установить камеру на audioListener до добавления слушателя в сцену, а не после.

Тем не менее, согласно документации Apple, если в сцене только одна камера, которая есть в моем случае, предполагается, что узел, на котором установлена ​​камера, автоматически по умолчанию становится pointOfView и, следовательно, по умолчанию также является audioListener.

На практике, похоже, это не так. - И поскольку pointOfView, по-видимому, не был связан с узлом, с которым была связана моя камера, казалось, что я не могу получить доступ к текущему узлу звуковой среды.

Таким образом, код, который я перечислил в моем вопросеработает, но с незначительной настройкой.

let engine = scnView.audioEngine
let environmentNode = scnView.audioEnvironmentNode
let pitch = AVAudioUnitVarispeed()

engine.attach(audioPlayer)
engine.attach(environmentNode)
engine.attach(pitch)

engine.connect(audioPlayer, to: pitch, format: file?.processingFormat)
engine.connect(pitch, to: environmentNode, format: file?.processingFormat)
engine.connect(environmentNode, to: engine.mainMixerNode, format: nil)

Как только это будет сделано, то, как и прежде, все, что мне нужно сделать, это создать SCNAudioPlayer из возвращенного AVAudioPlayerNode и связать SCNAudioPlayer с SCNNode, и все в порядке. ! :) Звук представлен в 3D-формате в зависимости от положения SCNNode и может быть легко изменен с помощью параметров подключенного AVAudioUnit.

Надеемся, что это поможет другим, и, пожалуйста, хорошего дня / выходных!

Ура! :)

ModGirl

...