Хобрук: Ваш путь к мастерству в программировании

Core Audio Matrix Mixer зависает и злоупотребляет памятью при установке количества входных или выходных элементов

Мне удалось построить и использовать простые звуковые графики с помощью Core Audio и Swift, но я не могу найти правильный способ использования Matrix Mixer. Когда я пытаюсь установить количество элементов, похоже, что программа входит в бесконечный цикл, который в конечном итоге использует много памяти и никогда не возвращается.

Возможно, это не совсем то же самое, что обсуждается здесь.

Самый простой возможный код для воспроизведения поведения:

    var graph = AUGraph()
    var filePlayerAU = AudioUnit()
    var mixerAU = AudioUnit()
    var outputAU = AudioUnit()

    NewAUGraph(&graph)


    // Add file player node
    var filePlayerNode = AUNode()
    var filePlayerDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Generator),
        componentSubType: OSType(kAudioUnitSubType_AudioFilePlayer),
        componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
        componentFlags: 0, componentFlagsMask: 0)
    CheckResult("Adding file player node", status: AUGraphAddNode(graph, &filePlayerDesc, &filePlayerNode))


    // Add matrix mixer node
    var mixerNode = AUNode()
    var mixerDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Mixer),
        componentSubType: OSType(kAudioUnitSubType_MatrixMixer),
        componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
        componentFlags: 0, componentFlagsMask: 0)
    CheckResult("Adding matrix mixer node", status: AUGraphAddNode(graph, &mixerDesc, &mixerNode))


    // Add output node
    var outputNode = AUNode()
    var outputDesc = AudioComponentDescription(componentType: OSType(kAudioUnitType_Output),
        componentSubType: OSType(kAudioUnitSubType_RemoteIO),
        componentManufacturer: OSType(kAudioUnitManufacturer_Apple),
        componentFlags: 0, componentFlagsMask: 0)
    CheckResult("Adding output node", status: AUGraphAddNode(graph, &outputDesc, &outputNode))


    // Graph must be opened before we can get node info, i.e. the Audio Units
    CheckResult("Opening graph", status: AUGraphOpen(graph))
    CheckResult("Getting file player node info", status: AUGraphNodeInfo(graph, filePlayerNode, nil, &filePlayerAU))
    CheckResult("Getting mixer node info", status: AUGraphNodeInfo(graph, mixerNode, nil, &mixerAU))
    CheckResult("Getting output node info", status: AUGraphNodeInfo(graph, outputNode, nil, &outputAU))


    var outputBusNumber: AudioUnitParameterValue = 1
    var propSize = UInt32(sizeof(AudioUnitParameterValue))
    // Setting default parameters for the mixer unit
    CheckResult("Setting mixer output elements count", status: AudioUnitSetProperty(mixerAU, AudioUnitPropertyID(kAudioUnitProperty_ElementCount), OSType(kAudioUnitScope_Output), 0, &outputBusNumber, propSize))

При выполнении этой последней строки программа зависает, и использование памяти становится запредельным. Сначала я попытался подключить график, но это не имеет никакого значения. Любая подсказка о том, как это должно быть сделано?

Функция CheckResult доступна здесь:

func CheckResult(msg:String, status:OSStatus) {

    print(msg + ": ")

    switch(Int(status)) {

    case 0:
        println("OK")

        // AudioToolbox
    case kAUGraphErr_NodeNotFound:
        println("Error:kAUGraphErr_NodeNotFound")

    case kAUGraphErr_OutputNodeErr:
        println("Error:kAUGraphErr_OutputNodeErr")

    case kAUGraphErr_InvalidConnection:
        println("Error:kAUGraphErr_InvalidConnection")

    case kAUGraphErr_CannotDoInCurrentContext:
        println("Error:kAUGraphErr_CannotDoInCurrentContext")

    case kAUGraphErr_InvalidAudioUnit:
        println("Error:kAUGraphErr_InvalidAudioUnit")

    case kAudioToolboxErr_InvalidSequenceType :
        println("kAudioToolboxErr_InvalidSequenceType")

    case kAudioToolboxErr_TrackIndexError :
        println("kAudioToolboxErr_TrackIndexError")

    case kAudioToolboxErr_TrackNotFound :
        println("kAudioToolboxErr_TrackNotFound")

    case kAudioToolboxErr_EndOfTrack :
        println("kAudioToolboxErr_EndOfTrack")

    case kAudioToolboxErr_StartOfTrack :
        println("kAudioToolboxErr_StartOfTrack")

    case kAudioToolboxErr_IllegalTrackDestination   :
        println("kAudioToolboxErr_IllegalTrackDestination")

    case kAudioToolboxErr_NoSequence        :
        println("kAudioToolboxErr_NoSequence")

    case kAudioToolboxErr_InvalidEventType      :
        println("kAudioToolboxErr_InvalidEventType")

    case kAudioToolboxErr_InvalidPlayerState    :
        println("kAudioToolboxErr_InvalidPlayerState")

    case kAudioUnitErr_InvalidProperty      :
        println("kAudioUnitErr_InvalidProperty")

    case kAudioUnitErr_InvalidParameter     :
        println("kAudioUnitErr_InvalidParameter")

    case kAudioUnitErr_InvalidElement       :
        println("kAudioUnitErr_InvalidElement")

    case kAudioUnitErr_NoConnection         :
        println("kAudioUnitErr_NoConnection")

    case kAudioUnitErr_FailedInitialization     :
        println("kAudioUnitErr_FailedInitialization")

    case kAudioUnitErr_TooManyFramesToProcess   :
        println("kAudioUnitErr_TooManyFramesToProcess")

    case kAudioUnitErr_InvalidFile          :
        println("kAudioUnitErr_InvalidFile")

    case kAudioUnitErr_FormatNotSupported       :
        println("kAudioUnitErr_FormatNotSupported")

    case kAudioUnitErr_Uninitialized        :
        println("kAudioUnitErr_Uninitialized")

    case kAudioUnitErr_InvalidScope         :
        println("kAudioUnitErr_InvalidScope")

    case kAudioUnitErr_PropertyNotWritable      :
        println("kAudioUnitErr_PropertyNotWritable")

    case kAudioUnitErr_InvalidPropertyValue     :
        println("kAudioUnitErr_InvalidPropertyValue")

    case kAudioUnitErr_PropertyNotInUse     :
        println("kAudioUnitErr_PropertyNotInUse")

    case kAudioUnitErr_Initialized          :
        println("kAudioUnitErr_Initialized")

    case kAudioUnitErr_InvalidOfflineRender     :
        println("kAudioUnitErr_InvalidOfflineRender")

    case kAudioUnitErr_Unauthorized         :
        println("kAudioUnitErr_Unauthorized")

    case kAudioFileUnspecifiedError:
        println("kAudioFileUnspecifiedError")

    case kAudioFileUnsupportedFileTypeError:
        println("kAudioFileUnsupportedFileTypeError")

    case kAudioFileUnsupportedDataFormatError:
        println("kAudioFileUnsupportedDataFormatError")

    case kAudioFileUnsupportedPropertyError:
        println("kAudioFileUnsupportedPropertyError")

    case kAudioFileBadPropertySizeError:
        println("kAudioFileBadPropertySizeError")

    case kAudioFilePermissionsError:
        println("kAudioFilePermissionsError")

    case kAudioFileNotOptimizedError:
        println("kAudioFileNotOptimizedError")

    case kAudioFileInvalidChunkError:
        println("kAudioFileInvalidChunkError")

    case kAudioFileDoesNotAllow64BitDataSizeError:
        println("kAudioFileDoesNotAllow64BitDataSizeError")

    case kAudioFileInvalidPacketOffsetError:
        println("kAudioFileInvalidPacketOffsetError")

    case kAudioFileInvalidFileError:
        println("kAudioFileInvalidFileError")

    case kAudioFileOperationNotSupportedError:
        println("kAudioFileOperationNotSupportedError")

    case kAudioFileNotOpenError:
        println("kAudioFileNotOpenError")

    case kAudioFileEndOfFileError:
        println("kAudioFileEndOfFileError")

    case kAudioFilePositionError:
        println("kAudioFilePositionError")

    case kAudioFileFileNotFoundError:
        println("kAudioFileFileNotFoundError")

    default:
        println("huh? (OSStatus: \(status))")
    }
}

Ответы:


1

Оказывается, проблема связана с использованием AudioUnitParameterValue, которое следует использовать только с AudioUnitSetParameter.

После изменения типа на UInt32 проблема исчезает.

Большое спасибо OOper на форумах разработчиков Apple за указание на мою глупую ошибку.

23.02.2015
Новые материалы

Создание кнопочного меню с использованием HTML, CSS и JavaScript
Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

Внедрите OAuth в свои веб-приложения для повышения безопасности
OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

Классы в JavaScript
class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

Как свинг-трейдеры могут использовать ИИ для больших выигрышей
По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

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

Обзор: Машинное обучение: классификация
Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

Разработка расширений Qlik Sense с qExt
Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..