Используя Xamarin, я хотел бы использовать AVAudioSinkNode для хранения и в конечном итоге передачи входящих аудиоданных с mi c с минимально возможной задержкой (не переходя прямо в AudioUnits и устаревшие AUGraphs). См. Мой закомментированный код ниже, где SinkNode подключен к InputNode по умолчанию. Это меня огорчает. Я использую Xamarin.Forms с простым классом зависимостей iOS. Я могу успешно подключить InputNode через узел fx (например, Reverb) и выйти на OutputNode. В этом случае я свернул свой код, чтобы сосредоточиться на проблеме:
public unsafe class AudioEngine : IAudioEngine
{
AVAudioEngine engine;
AVAudioInputNode input;
AVAudioSinkNode sink;
public AudioEngine()
{
ActivateAudioSession();
}
protected void ActivateAudioSession()
{
var session = AVAudioSession.SharedInstance();
session.SetCategory(AVAudioSessionCategory.Playback, AVAudioSessionCategoryOptions.DuckOthers);
session.SetActive(true);
session.SetPreferredIOBufferDuration(0.0007, out error); // 32 byte buffer, if possible!
engine = new AVAudioEngine();
input = engine.InputNode; // to save on typing
input.Volume = 0.5f;
var format = input.GetBusInputFormat(0); // used for fx connections, but not used in this snippet. If I use this in the Input -> Sink connection, it crashes.
sink = new AVAudioSinkNode(sinkReceiverHandler);
engine.AttachNode(sink);
try
{
//-----------------------------------------------------
// Param #3 (format) is nil in all the Apple Documentation and multiple examples
// In place of nil, **NSNull.Null** isn't accepted.
// In place of nil, **null** throws a System.NullReferenceException. (see stack dump)
// In place of nil, using the **InputNode's format** crashes with
// something about missing the Trampolines.g.cs file... no clue...
engine.Connect(input, sink, **null**); // null doesn't work in place of nil.
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace); // Exception messages included below
}
engine.Prepare();
engine.StartAndReturnError(out error);
}
private unsafe int sinkReceiverHandler(AudioToolbox.AudioTimeStamp timeStamp, uint frames, ref AudioToolbox.AudioBuffers inputData)
{
// Do stuff with the data...
return 0;
}
}
Я нашел сообщение, связанное с использованием nil в качестве параметра в Xamarin. iOS, в котором говорится, что автор библиотеки должен включить аргумент [NullAllowed]:
Как присвоить чему-то значение nil с помощью Xamarin. iOS
Мой вопрос: Я упускаю что-то очевидное или это упущение в определении библиотеки Xamarin? Я всегда предполагаю, что это мой недостаток опыта, но если это ошибка, как мне go сообщить об этом в Xamarin?
Дополнительный вопрос: Если это это глюк, есть ли способ обхода? Могу ли я go вручную настроить определение библиотеки Xamarin? (что, я уверен, сломалось бы при любых обновлениях.) Или я могу создать небольшую библиотеку, используя Swift, которую я затем импортирую в свой проект Xamarin?
Просто пытаюсь придумать варианты. Спасибо за прочтение! Ниже представлен дамп стека, когда я использую null вместо nil (опять же ... NSNull.Null в этом случае не считается допустимым типом. Он просто не компилируется):
{System.NullReferenceException: ссылка на объект не установлена на экземпляр объекта в AVFoundation.AVAudioFormat.op_Equality (AVFoundation.AVAudioFormat a, AVFoundation.AVAudioFormat b) [0x00000] в /Library/Frameworks/Xamarin.iOS. framework / Versions / 13.18.3.2 / src / Xamarin.iOS / AVFoundation / AVAudioFormat.cs: 27 в AVFoundation.AVAudioEngine.Connect (AVFoundation.AVAudioNode sourceNode, AVFoundation.AVAudioNode targetNode, AVFoundation.AVAudioFormat / format] [Library в формате / 0 Frameworks / Xamarin. iOS .framework / Versions / 13.18.3.2 / src / Xamarin.iOS / AVAudioEngine.g.cs: 120 при udptest. iOS .AudioEngine.ActivateAudioSession () [0x0009b] в / Users / eludema / dev / xamarin / udptest / udptest.iOS / AudioEngine.cs: 43}
СПАСИБО!