Example: /AVFoundation/AVAudioEngine manual rendering

Online Documentation   -   Statistics   -   FAQ   -   Plugin Parts (All, Dependencies)   -   Class hierarchy

New in Version 22.2 22.3 22.4 22.5 23.0 23.1 23.2 23.3 23.4 23.5 24.0 24.1

The list of the   topics,   classes,   interfaces,   controls,   modules,   global methods by category,   global methods by name,   screenshots,   licenses   and   examples.

Platforms to show: All Mac Windows Linux Cross-Platform

/AVFoundation/AVAudioEngine manual rendering


Required plugins for this example: MBS MacBase Plugin, MBS Main Plugin, MBS AVFoundation Plugin

You find this example project in your Plugins Download as a Xojo project file within the examples folder: /AVFoundation/AVAudioEngine manual rendering

This example is the version from Sun, 2nd Jan 2021.

Project "AVAudioEngine manual rendering.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "&Delete"
Const kFileQuit = "&Quit"
Const kFileQuitShortcut = ""
EventHandler Sub Open() Dim InputFile As FolderItem = GetFolderItem("/Users/cs/Desktop/test.MOV", FolderItem.PathTypeNative) If Not InputFile.Exists Then // please change path! Break return End If Dim outputFile As FolderItem = SpecialFolder.Desktop.Child("test.aac") Call export(InputFile, 1.0, 1.0, outputFile) End EventHandler
Function export(InputFile as FolderItem, floRate as double, floPitch as Double, DestFile as FolderItem) As Boolean // floRate = Float of playback rate (e.g. 0.5 = 50% speed) // floPitch = Float for pitch change required // DestFile = Filename of file where to put System.debuglog("Exporting...") Dim engine As New AVAudioEngineMBS Dim player As New AVAudioPlayerNodeMBS Dim pitchEffect As New AVAudioUnitTimePitchMBS // We found the file in the folder. system.debuglog("Audio file obtained") Dim error As NSErrorMBS Dim file As New AVAudioFileMBS(InputFile, error) If error <> Nil Then Dim e As String = error.LocalizedDescription System.DebugLog "Failed to open file: "+e Break Return false End If system.debuglog("File opened OK") Dim Format As AVAudioFormatMBS = file.processingFormat // Set the pitch-shift amount (100 cents = 1 semitone). pitchEffect.pitch = floPitch // semitone pitchEffect.overlap = 32.0 // more overlapping windows = less artifacts - Max = 32 pitchEffect.rate = floRate // Rate // Add nodes to engine. engine.attachNode(player) engine.attachNode(pitchEffect) // Connect the player's output to the effect's input. engine.connect(player, pitchEffect, file.processingFormat) // Connect the effect's output to the main mixer input. engine.connect(pitchEffect, engine.mainMixerNode, file.processingFormat) // Schedule the file and start the engine. player.scheduleFile(file, Nil) // Set engine to manual rendering. // The maximum number of frames the engine renders in any single render call. Dim maxFrames As Integer = 4096 Dim mode As Integer = AVAudioEngineMBS.ManualRenderingModeOffline Dim r As Boolean r = engine.enableManualRenderingMode(mode, Format, maxFrames, error) If error <> Nil Then Dim e As String = error.LocalizedDescription System.DebugLog "Failed to enable manual rendering mode: "+e Break Return False End If // Start engine. If engine.startAndReturnError(error) then System.debuglog("Engine started") Else Dim e As String = error.LocalizedDescription System.DebugLog "Engine failed to start: "+e Break Return False End If // Play the file. player.play // The output buffer to which the engine renders the processed data. dim buffer as new AVAudioPCMBufferMBS(engine.manualRenderingFormat, engine.manualRenderingMaximumFrameCount) // Setup our output file to export to. Dim outputFile As New AVAudioFileMBS(DestFile, file.fileFormat.settings, error) If error <> Nil Then Dim e As String = error.LocalizedDescription System.DebugLog "Failed to create output file: "+e Break Return false End If // Need to work out what the new length would be based on the rate passed. // This prevents output ending early or having silence at end of output. Dim newLength As Double = file.length * (1.0 / floRate) newLength = Ceil(newLength) // round up Dim newLengthInt As Integer = newLength // Render output to buffer and output buffer content to file in loop. While engine.manualRenderingSampleTime < newLength // Work out how many frames to render. Dim frameCount As Int64 = newLengthInt - engine.manualRenderingSampleTime Dim framesToRender As Int64 = Min(frameCount, buffer.frameCapacity) // Render offline to buffer. Dim status As Integer = engine.renderOffline(framesToRender, buffer, error) If error <> Nil Then Dim e As String = error.LocalizedDescription System.DebugLog "Failed to render offline: "+e Break Return False End If // Check if we had success. Select Case status Case AVAudioEngineMBS.ManualRenderingStatusSuccess // The data rendered successfully. Write it to the output file. Call outputFile.writeFromBuffer(buffer, error) If error <> Nil Then Dim e As String = error.LocalizedDescription System.DebugLog "Failed to write buffer: "+e Break Return False End If Case AVAudioEngineMBS.ManualRenderingStatusInsufficientDataFromInputNode // Applicable only when using the input node as one of the sources. Break Case AVAudioEngineMBS.ManualRenderingStatusCannotDoInCurrentContext // The engine couldn't render in the current render call. // Retry in the next iteration. Break Case AVAudioEngineMBS.ManualRenderingStatusError // An error occurred while rendering the audio. System.DebugLog("Manual offline rendering failed.") Break Else // Something unexpected. // We'll retry in the next iteration. Break End Select Wend // Stop the player node and engine. player.stop engine.stop player = Nil engine = Nil System.debuglog("Audio file exported") return true // catch all exceptions Exception re As RuntimeException System.DebugLog "Got exception: "+Introspection.GetType(re).name System.DebugLog Str(re.errorNumber)+": "+re.message Break Return False End Function
End Class
Class MainWindow Inherits Window
End Class
MenuBar MainMenuBar
MenuItem FileMenu = "&File"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Edit"
MenuItem EditUndo = "&Undo"
MenuItem EditSeparator1 = "-"
MenuItem EditCut = "Cu&t"
MenuItem EditCopy = "&Copy"
MenuItem EditPaste = "&Paste"
MenuItem EditClear = "#App.kEditClear"
MenuItem EditSeparator2 = "-"
MenuItem EditSelectAll = "Select &All"
End MenuBar
End Project

The items on this page are in the following plugins: MBS AVFoundation Plugin.


💬 Ask a question or report a problem